Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Рисование в WPF с помощью DrawingVisual

14K
10 июля 2012 года
artem_kvadro
63 / / 30.07.2007
Нужно в приложении WPF рисовать график по точкам. Line, Polyline и прочее не подходят, потому что точек много и тормоза. Пытаюсь использовать DrawingVisual по примеру: создал свой класс MyField, унаследованный от FrameworkElement и поместил его на форму
 
Код:
....
    <Grid Width="60" Height="60">
        <local:MyField/>
    </Grid>
Рисую пару линий:
 
Код:
var visual = new DrawingVisual();
            children.Add(visual);

            using (var dc = visual.RenderOpen())
            {
                dc.DrawLine(new Pen(Brushes.Black, 1), new Point(0, 0), new Point(400, 400));
                dc.DrawLine(new Pen(Brushes.Black, 1), new Point(0, 400), new Point(400, 0));
            }
Проблема в том, что линии рисуются по всей клиентской области окна, поверх остальных элементов WPF, несмотря на то, что явно задан размер Grid. Как этого избежать?
40K
10 июля 2012 года
D129
228 / / 18.04.2012
Я боролся с тормозами не так.
"Точек много" - это что значит?
Зачем пытаться рисовать больше, чем экран может отобразить?
Я разделил - точная модель (где много точек) - отдельно, а перед отображением она пересчитывается в масштаб экрана (и это, даже на современном мониторе, ну 2000 х 1000) и точек остается мало. И даже винформы не тормозили.
14K
10 июля 2012 года
artem_kvadro
63 / / 30.07.2007
У меня тормоза очень заметно проявляются уже на 10 линиях по 1000 точек на каждую (на Core i3 с 3 ГБ ОЗУ). Пусть обычно и не нужно одновременно просматривать 10 графиков, но при большом разрешении точек будет больше на каждый график.
40K
10 июля 2012 года
D129
228 / / 18.04.2012
значит вы перегружаете процессор какими-то лишними перерисовками или перерасчетами.

Сами подумайте - не могут 10 линий грузить современный 3д акселератор. Это же не ZX - Spectrum 48. :-)
А я и на нем больше (300) линий рисовал.
Просто хочу сказать, что попытка не использовать линии (по определению оптимизированные и отлаженные) и замена их своим аналогом - проблему не решит.
14K
10 июля 2012 года
artem_kvadro
63 / / 30.07.2007
Нет, других расчетов пока нет, пустой проект. Здесь же не в том беда, сколько линий, а в том, что я их строю по большому количеству точек, то есть из объектов Point. Попробуйте сами вот такой код:

Код:
public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
                        this.Loaded +=new RoutedEventHandler(MainWindow_Loaded);
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            Polyline[] lines = new Polyline[10];
            for (int i = 0; i < lines.Length; ++i)
            {
                lines[i] = new Polyline();
                lines[i].StrokeThickness = 1;
                lines[i].Stroke = new SolidColorBrush(Colors.Blue);

                PointCollection pc = new PointCollection();
                Random rand = new Random();
                for (int j = 0; j < 1000; ++j)
                {
                    int x = rand.Next(1200);
                    int y = rand.Next(800);
                    Point point = new Point(x, y);
                    pc.Add(point);
                }

                lines[i].Points = pc;
                this.grid1.Children.Add(lines[i]); //grid1 - описан в xaml как контейнер главного окна
            }
        }
Потом поперетаскивайте и порастягивайте окно.
И еще полезная ссылка об этом: [url]http://blogs.msdn.com/b/dsimmons/archive/2010/11/28/simple-wpf-2d-graphics-drawingvisual.aspx
40K
11 июля 2012 года
D129
228 / / 18.04.2012
Попробуйте заменить контрол - возмите какой нибудь PictureBox (не помню как это в WPF называется)
и рисуйте на нем.
Вам ведь функциональность Polyline не нужна - а систему она грузит.

Чинил я как-то програмку, в которой контролы (кнопочки, меточки, комбобоксы) добавлялись динамически, из базы данных.
И программка падала, потому, что количество контролов в приложении - ограничено системой, и в зависимости от компьютера - от 1500 до 2500 штук.

Думаю, что тут вы тоже к границе подошли.
14K
12 июля 2012 года
artem_kvadro
63 / / 30.07.2007
[QUOTE="D129"]Попробуйте заменить контрол - возмите какой нибудь PictureBox (не помню как это в WPF называется)
и рисуйте на нем.
Вам ведь функциональность Polyline не нужна - а систему она грузит.[/QUOTE]
А поподробнее? Что за PictureBox? Кроме DrawingVisual и обычного Canvas ничего не нашел. И чем можно заменить Polyline?
40K
12 июля 2012 года
D129
228 / / 18.04.2012
Ну а если вот так:


Код:
public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
       


            Polyline[] lines = new Polyline[10];
            for (int i = 0; i < lines.Length; ++i)
            {
                lines[i] = new Polyline();
                lines[i].StrokeThickness = 1;
                lines[i].Stroke = new SolidColorBrush(Colors.Blue);

                PointCollection pc = new PointCollection();
                Random rand = new Random();
                for (int j = 0; j < 1000; ++j)
                {
                    int x = rand.Next(1200);
                    int y = rand.Next(800);
                    Point point = new Point(x, y);
                    pc.Add(point);
                }

                lines[i].Points = pc;
                this.Grid1.Children.Add(lines[i]); //grid1 - описан в xaml как контейнер главного окна

                this.Grid1.SizeChanged += new SizeChangedEventHandler(Grid1_SizeChanged);


            }
            Thread.Sleep(1000);
           

        }


        Image image1;
        void Grid1_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            if (image1 == null)
            {
                RenderTargetBitmap bitmap = new RenderTargetBitmap(400, 300, 96, 96, PixelFormats.Pbgra32);
                bitmap.Render(this.Grid1);
                image1 = new Image();
                image1.Source = bitmap;

                this.Grid1.Children.Clear();

                this.Grid1.Children.Add(image1);

            }
        }
    }
}

Знаете кого-то, кто может ответить? Поделитесь с ним ссылкой.

Ваш ответ

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог