WPF: 使用DrawVisual提高大数据量时的绘图性能

在WPF中绘制形状时,如果数据量大(例如一条Polyline有10万多个数据点),绘制过程会很慢。目前能想到的解决办法有:

1. 将形状绘制在位图里。
2. 升级到最新.net4.5,WPF性能提升不少(这个要赞)
3. 使用DrawVisual来实现画图。

 

下面主要谈一下DrawVisual的用法。Visual 类的层次结构如下:

从 Visual 对象派生的类的示意图

DrawingVisual 继承自Visual,是一个用于呈现形状、图像或文本的轻量绘图类。 此类之所以被视为轻量,是因为它不提供布局或事件处理功能,从而能够改善运行时性能。 因此,绘图最适于背景和剪贴画。 DrawingVisual 可用于创建自定义可视化对象。

在下面代码中,创建了一个继承自Canvas的类DrawingCanvas。该类实现了Visual的一些基本操作,并添加了用DrawVisual绘制Polyline方法。

using System.Collections.Generic;

using System.Windows.Controls;

using System.Windows.Media;

using System.Windows;



namespace PostViewer

{

    public class DrawingCanvas : Canvas

    {

        private List<Visual> visuals = new List<Visual>();

    

        //获取Visual的个数

        protected override int VisualChildrenCount

        {

            get { return visuals.Count; }

        }



        //获取Visual

        protected override Visual GetVisualChild(int index)

        {

            return visuals[index];

        }

    

        //添加Visual

        public void AddVisual(Visual visual)

        {

            visuals.Add(visual);



            base.AddVisualChild(visual);

            base.AddLogicalChild(visual);

        }



        //删除Visual

        public void RemoveVisual(Visual visual)

        {

            visuals.Remove(visual);



            base.RemoveVisualChild(visual);

            base.RemoveLogicalChild(visual);

        }



        //命中测试

        public DrawingVisual GetVisual(Point point)

        {

            HitTestResult hitResult = VisualTreeHelper.HitTest(this, point);

            return hitResult.VisualHit as DrawingVisual;

        }



        //使用DrawVisual画Polyline

        public Visual Polyline(PointCollection points, Brush color, double thinkness)

        {

            DrawingVisual visual = new DrawingVisual();

            DrawingContext dc = visual.RenderOpen();

            Pen pen = new Pen(Brushes.Red, 3);

            pen.Freeze();  //冻结画笔,这样能加快绘图速度



            for (int i = 0; i < points.Count - 1; i++ )

            {

                dc.DrawLine(pen, points[i], points[i+1]);

            }



            dc.Close();

            return visual;

        }

    }

}    

 

绘制其他形状的方法,请参见MSDN中的DrawingContext类

 

你可能感兴趣的:(大数据量)