Visual对象之DrawingContext.DrawRectangle在有的状态下似乎并不能提高性能

很多书上都提到使用Visual对象绘制图形可以提高绘图效率,但是经过本人亲测,结果却发现DrawingContext.DrawRectangle的效率远低于使用UIElement.Children.Add(UIElement element)方法。

此时方法如下:

前台窗体有两个canvas,一个里面直接放矩形Rectangle,另外一个放自己写的继承自Canvas的子类控件DrawingCanvas;

他们的面积都为800×600。

经测试,使用DrawingContext.DrawRectangle绘制15000个正方形需耗时35秒左右,而使用基础类Canvas.Children.Add(UIElement element)的方法只需耗时3.7秒。

DrawingContext.DrawRectangle的代码

 
1:     private void btnDrawing_Click_1(object sender, RoutedEventArgs e)
   2:          {
   3:              //自己写的继承自Canvas的子类控件DrawingCanvas
   4:              ZhangAi = new DrawingCanvas();
   5:              DrawingPlan.Children.Add(ZhangAi);
   6:              Canvas.SetLeft(ZhangAi, 0);
   7:              Canvas.SetTop(ZhangAi, 0);
   8:              Time1 = DateTime.Now;
   9:              Random rd = new Random();
  10:   
  11:              for (int i = 0; i < Convert.ToInt16(CellNumber.Text); i++)
  12:              {
  13:                  //自己写的继承自DrawingVisual的子类
  14:                  MyDrawingVisual visual = new MyDrawingVisual();
  15:                  visual.Tag = new Random().Next(30).ToString();
  16:                  using (DrawingContext dc = visual.RenderOpen())
  17:                  {
  18:                      dc.DrawRectangle(drawingBrush, drawingPen,
  19:                          new Rect(new Point(rd.Next(800), rd.Next(600)), new Size(GridSize, GridSize)));
  20:                  }
  21:                  ZhangAi.AddVisual(visual);
  22:   
  23:   
  24:              }
  25:          }

 

Canvas.Children.Add(UIElement element)的方法

 

 
 1:   private void btnGeneral_Click_1(object sender, RoutedEventArgs e)
   2:          {
   3:              Time1 = DateTime.Now;
   4:              Random rd = new Random();
   5:   
   6:              for (int i = 0; i < Convert.ToInt16(CellNumber.Text); i++)
   7:              {
   8:   
   9:                  rect = new Rectangle();
  10:                  rect.Fill = new SolidColorBrush(Colors.GreenYellow);
  11:                  rect.Opacity = 0.3;
  12:                  rect.Stroke = new SolidColorBrush(Colors.Gray);
  13:                  rect.Width = GridSize;
  14:                  rect.Height = GridSize;
  15:                  testCanvas.Children.Add(rect);
  16:                  Canvas.SetLeft(rect, rd.Next(800));
  17:                  Canvas.SetTop(rect, rd.Next(600));
  18:              }
  19:          }

 

下面是DrawingCanvas 类

 

 
 1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Text;
   4:  using System.Windows.Media;
   5:  using System.Windows.Controls;
   6:  using System.Windows;
   7:   
   8:  namespace WPFGameTest
   9:  {
  10:      public class DrawingCanvas : Canvas
  11:      {
  12:          private List<Visual> visuals = new List<Visual>();
  13:   
  14:          protected override Visual GetVisualChild(int index)
  15:          {
  16:              return visuals[index];
  17:          }
  18:          protected override int VisualChildrenCount
  19:          {
  20:              get
  21:              {
  22:                  return visuals.Count;
  23:              }
  24:          }
  25:   
  26:          public void AddVisual(Visual visual)
  27:          {
  28:              visuals.Add(visual);
  29:   
  30:              base.AddVisualChild(visual);
  31:              base.AddLogicalChild(visual);
  32:             
  33:          }
  34:   
  35:          public void DeleteVisual(Visual visual)
  36:          {
  37:              visuals.Remove(visual);
  38:   
  39:              base.RemoveVisualChild(visual);
  40:              base.RemoveLogicalChild(visual);
  41:          }
  42:   
  43:          public MyDrawingVisual GetVisual(Point point)
  44:          {
  45:              HitTestResult hitResult = VisualTreeHelper.HitTest(this, point);
  46:              return hitResult.VisualHit as MyDrawingVisual;
  47:          }
  48:   
  49:          private List<DrawingVisual> hits = new List<DrawingVisual>();
  50:          public List<DrawingVisual> GetVisuals(Geometry region)
  51:          {
  52:              hits.Clear();
  53:              GeometryHitTestParameters parameters = new GeometryHitTestParameters(region);
  54:              HitTestResultCallback callback = new HitTestResultCallback(this.HitTestCallback);
  55:              VisualTreeHelper.HitTest(this, null, callback, parameters);
  56:              return hits;
  57:          }
  58:   
  59:          private HitTestResultBehavior HitTestCallback(HitTestResult result)
  60:          {
  61:              GeometryHitTestResult geometryResult = (GeometryHitTestResult)result;
  62:              DrawingVisual visual = result.VisualHit as DrawingVisual;
  63:              if (visual != null &&
  64:                  geometryResult.IntersectionDetail == IntersectionDetail.FullyInside)
  65:              {
  66:                  hits.Add(visual);
  67:              }
  68:              return HitTestResultBehavior.Continue;
  69:          }
  70:   
  71:      }
  72:  }

下面是MyDrawingVisual 类

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media;

namespace WPFGameTest
{
    public class MyDrawingVisual : DrawingVisual
    {
        string _Tag;

        public string Tag
        {
            get { return _Tag; }
            set { _Tag = value; }
        }
        // 摘要:
        //     初始化 System.Windows.Media.DrawingVisual 类的新实例。

        public MyDrawingVisual() { }

        // 摘要:
        //     获取 System.Windows.Media.DrawingVisual 对象的绘图内容。
        //
        // 返回结果:
        //     获取一个 System.Windows.Media.DrawingGroup 类型的值,该值表示 System.Windows.Media.DrawingVisual
        //     中 System.Windows.Media.Drawing 对象的集合。
        //public DrawingGroup Drawing { get; }

        // 摘要:
        //     确定可视对象的边界中是否存在几何图形值。
        //
        // 参数:
        //   hitTestParameters:
        //     一个 System.Windows.Media.GeometryHitTestParameters 类型的值,指定命中测试所依据的 System.Windows.Media.Geometry。
        //
        // 返回结果:
        //     一个 System.Windows.Media.GeometryHitTestResult 类型的值。
        protected GeometryHitTestResult HitTestCore(GeometryHitTestParameters hitTestParameters)
        {
            return base.HitTestCore(hitTestParameters);
        }
        //
        // 摘要:
        //     确定在 System.Windows.Media.DrawingVisual 对象的边界中是否存在点坐标值。
        //
        // 参数:
        //   hitTestParameters:
        //     一个 System.Windows.Media.PointHitTestParameters 类型的值,指定命中测试所依据的 System.Windows.Point。
        //
        // 返回结果:
        //     一个 System.Windows.Media.HitTestResult 类型的值,表示从命中测试中返回的 System.Windows.Media.Visual。
        protected HitTestResult HitTestCore(PointHitTestParameters hitTestParameters)
        {
            return base.HitTestCore(hitTestParameters);
        }

        //
        // 摘要:
        //     打开用于呈现的 System.Windows.Media.DrawingVisual 对象。返回的 System.Windows.Media.DrawingContext
        //     值可用于呈现为 System.Windows.Media.DrawingVisual。
        //
        // 返回结果:
        //     一个 System.Windows.Media.DrawingContext 类型的值。
        public DrawingContext RenderOpen()
        {
            return base.RenderOpen();
        }
    }

}

 

 

 

你可能感兴趣的:(drawRect)