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類

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM