zoukankan      html  css  js  c++  java
  • 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类

  • 相关阅读:
    uva 1606 极角扫描
    Codeforces Round #304 (Div. 2) 题解
    Codeforces Round #306 (Div. 2) 题解
    Codeforces Round #299 (Div. 2) 题解
    树链剖分专题
    bzoj 1036: [ZJOI2008]树的统计Count
    bzoj 1007: [HNOI2008]水平可见直线
    bzoj 1003: [ZJOI2006]物流运输trans
    Codeforces Round #301 (Div. 2) 题解
    bzoj 1026: [SCOI2009]windy数
  • 原文地址:https://www.cnblogs.com/xpvincent/p/2864902.html
Copyright © 2011-2022 走看看