在WPF中绘制大量视觉元素的建议(简单)方法?

时间:2010-04-26 22:21:44

标签: c# wpf performance drawing

我正在编写一个具有大(~50000像素宽)“画布”类型区域的界面,该区域用于以相当新颖的方式显示大量数据。这涉及许多线条,矩形和文本。用户可以滚动浏览整个画布。

目前我只是使用标准的Canvas面板,其上放置了各种形状。这很容易做到:构造一个形状,分配一些坐标,并将它附加到Canvas。不幸的是,它很慢(构建子项,而不是实际渲染)。

我调查了some alternatives,这有点令人生畏。我不需要任何花哨的东西 - 只是能够有效地构建和放置坐标平面中的对象。如果我得到的只是线条,彩色矩形和文字,我会很高兴。

我是否需要在GeometryGeometry Group容器内的GeometryDrawing内的Panel个{{1}}个实例?

注意:如果可能的话,我想在同一个空间中包含文字和图形(即彩色矩形)。

3 个答案:

答案 0 :(得分:2)

形状相当重。您应该考虑使用图形路径。当用户不需要与绘图的各个部分进行交互时,这些更有效 - 有时甚至是。

答案 1 :(得分:1)

尽量不要创建不需要的形状,并回收已有的形状。基本上没有用户会看到整个屏幕,所以不要有看不见的形状。不要创建新的,你可以避免 - 基本上保持形状在“准备”列表中掉落,所以你可以重复使用它们。

答案 2 :(得分:-1)

如果你有大量的Shape实例,你可以异步地(在工作线程上)构造它们,并通过Dispatcher排队实际的Add操作。这里的想法是UI不会立即完成,但用户可以立即开始交互,同时元素继续加载。


编辑:上述内容不正确。 WPF确实要求在UI线程上创建Visual元素。你仍然可以使用这样的模式完成这种“懒惰”的视觉加载:

    private Random _random = new Random();

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        Thread testThread = new Thread(TestThread);
        testThread.Start();
    }

    private void TestThread()
    {
        for (int i = 0; i < 1000; i++)
        {
            Dispatcher.BeginInvoke((Action)CreateShape);
        }
    }

    private void CreateShape()
    {
        var shape = new Rectangle();
        shape.Width = _random.Next(10, 50);
        shape.Height = _random.Next(10, 50);
        shape.Fill = new SolidColorBrush(Colors.Red);
        Canvas.SetLeft(shape, _random.Next(0, 400));
        Canvas.SetTop(shape, _random.Next(0, 200));
        LayoutRoot.Children.Add(shape);            
    }

这基本上将要在UI线程上“异步”运行的任务排队(即每当消息泵正在服务时),这样您就可以在执行“长”UI更新时保持响应性。