很多书上都提到使用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的代码

:     private void btnDrawing_Click_1(object sender, RoutedEventArgs e)
   :          {
   :              //自己写的继承自Canvas的子类控件DrawingCanvas
   :              ZhangAi = new DrawingCanvas();
   :              DrawingPlan.Children.Add(ZhangAi);
   :              Canvas.SetLeft(ZhangAi, );
   :              Canvas.SetTop(ZhangAi, );
   :              Time1 = DateTime.Now;
   :              Random rd = new Random();
  :
  :              ; i < Convert.ToInt16(CellNumber.Text); i++)
  :              {
  :                  //自己写的继承自DrawingVisual的子类
  :                  MyDrawingVisual visual = new MyDrawingVisual();
  :                  visual.Tag = ).ToString();
  :                  using (DrawingContext dc = visual.RenderOpen())
  :                  {
  :                      dc.DrawRectangle(drawingBrush, drawingPen,
  :                          ), rd.Next()), new Size(GridSize, GridSize)));
  :                  }
  :                  ZhangAi.AddVisual(visual);
  :
  :
  :              }
  :          }

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

 :   private void btnGeneral_Click_1(object sender, RoutedEventArgs e)
   :          {
   :              Time1 = DateTime.Now;
   :              Random rd = new Random();
   :
   :              ; i < Convert.ToInt16(CellNumber.Text); i++)
   :              {
   :
   :                  rect = new Rectangle();
  :                  rect.Fill = new SolidColorBrush(Colors.GreenYellow);
  :                  rect.Opacity = 0.3;
  :                  rect.Stroke = new SolidColorBrush(Colors.Gray);
  :                  rect.Width = GridSize;
  :                  rect.Height = GridSize;
  :                  testCanvas.Children.Add(rect);
  :                  Canvas.SetLeft(rect, rd.Next());
  :                  Canvas.SetTop(rect, rd.Next());
  :              }
  :          }

下面是DrawingCanvas 类

 :  using System;
   :  using System.Collections.Generic;
   :  using System.Text;
   :  using System.Windows.Media;
   :  using System.Windows.Controls;
   :  using System.Windows;
   :
   :  namespace WPFGameTest
   :  {
  :      public class DrawingCanvas : Canvas
  :      {
  :          private List<Visual> visuals = new List<Visual>();
  :
  :          protected override Visual GetVisualChild(int index)
  :          {
  :              return visuals[index];
  :          }
  :          protected override int VisualChildrenCount
  :          {
  :              get
  :              {
  :                  return visuals.Count;
  :              }
  :          }
  :
  :          public void AddVisual(Visual visual)
  :          {
  :              visuals.Add(visual);
  :
  :              base.AddVisualChild(visual);
  :              base.AddLogicalChild(visual);
  :
  :          }
  :
  :          public void DeleteVisual(Visual visual)
  :          {
  :              visuals.Remove(visual);
  :
  :              base.RemoveVisualChild(visual);
  :              base.RemoveLogicalChild(visual);
  :          }
  :
  :          public MyDrawingVisual GetVisual(Point point)
  :          {
  :              HitTestResult hitResult = VisualTreeHelper.HitTest(this, point);
  :              return hitResult.VisualHit as MyDrawingVisual;
  :          }
  :
  :          private List<DrawingVisual> hits = new List<DrawingVisual>();
  :          public List<DrawingVisual> GetVisuals(Geometry region)
  :          {
  :              hits.Clear();
  :              GeometryHitTestParameters parameters = new GeometryHitTestParameters(region);
  :              HitTestResultCallback callback = new HitTestResultCallback(this.HitTestCallback);
  :              VisualTreeHelper.HitTest(this, null, callback, parameters);
  :              return hits;
  :          }
  :
  :          private HitTestResultBehavior HitTestCallback(HitTestResult result)
  :          {
  :              GeometryHitTestResult geometryResult = (GeometryHitTestResult)result;
  :              DrawingVisual visual = result.VisualHit as DrawingVisual;
  :              if (visual != null &&
  :                  geometryResult.IntersectionDetail == IntersectionDetail.FullyInside)
  :              {
  :                  hits.Add(visual);
  :              }
  :              return HitTestResultBehavior.Continue;
  :          }
  :
  :      }
  :  }

下面是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();
        }
    }

}


Visual对象之DrawingContext.DrawRectangle在有的状态下似乎并不能提高性能的更多相关文章

  1. Java对象在Hibernate持久化层的状态

    -临时状态:刚用new语句创建对象,还没有被持久化,并且不处于Session缓存中.处于临时状态的java对象被称为临时对象. -持久化状态:已经被持久化,并且加入到Session的缓存中.处于持久化 ...

  2. WPF中实现图片文件转换成Visual对象,Viewport3D对象转换成图片

    原文:WPF中实现图片文件转换成Visual对象,Viewport3D对象转换成图片 1.图片文件转换成Visual对象 private Visual CreateVisual(string imag ...

  3. Hibernate实体对象的生命周期(三种状态)

    瞬时状态(Transient) 通过new创建对象后,对象并没有立刻持久化,它并未与数据库中的数据有任何关联,此时Java对象的状态为瞬时状态. Session对于瞬时状态的Java对象是一无所知的, ...

  4. easyui 在编辑状态下,动态修改其他列值。

    首先是自定义了一个方法uodateColumn更新列值 /** *自定义的修改列值方法 */ $.extend($.fn.datagrid.methods, { updateColumn: funct ...

  5. SpringMVC成员变量并发状态下使用测试

    1.SpringMVC默认是单例的,使用成员变量在并发状态下该成员变量的值是被共享的 测试平台 我们目前正在开发的电商项目  (架构组成SpringCloud + SpringBoot + Sprin ...

  6. 线程状态及各状态下与锁和CPU的关系

    线程的状态 Thread.State枚举类型中定义了线程的六种状态:NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING和TERMINATED. 线程在某一时刻只能拥有 ...

  7. android 控件在不同状态下的内容样式与背景样式

    1 控件内容(如字体颜色)在不同状态下有不同的表现色ref:http://developer.android.com/guide/topics/resources/color-list-resourc ...

  8. wpf,离线状态下部分功能不可用。

    离线状态下,设置按钮的不可用.通过改变资源字典的值. App.xaml 文件下添加如下 xmlns:sys="clr-namespace:System;assembly=mscorlib&q ...

  9. 利用selector设置ImageButton不同状态下的背景图片

    1.自定义MyButton类 public class MyButton extends Button { //This constructormust be public MyButton(Cont ...

随机推荐

  1. win7共享wifi

    已管理员身份打开 命令提示符 netsh wlan set hostednetwork mode=allow ssid=abcde key=123456 netsh wlan start hosted ...

  2. 关于kinect的安装与配置工作

    一 关于kinect的安装与配置工作 首先要注意的是,使用kinect进行开发,目前有两种不同的驱动方案,经测试这两种方案的驱动是不能兼容的,所以请务必选定其中一种(最好是卸载另外一种). 方案一:使 ...

  3. SAP 审计

    SAP 权限审计:SA38--- RSUSR002 还有其它事务码待续,,,

  4. 设置SAPgui自动退出功能

    当客户端长时间没有使用时,为了不占用SAP服务器的资源,我们可以设置当客户端在一段时间没有 进行操作时自动退出SAP系统. 设置步骤如下: 用Tcode rz10打开参数配置窗口,选择你当前的实例参数 ...

  5. 98. Validate Binary Search Tree

    Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as ...

  6. JavaScript个人学习记录总结(二)——验证表单输入之模式匹配

    该示例检查从文本窗口部件中获取姓名和电话号码这两个表单数据的有效性.当文本框中的值发生变化时,即引发一个change事件,从而可以调用一个函数来检查这两个输入值的格式是否正确. validator.h ...

  7. HDU-4777 Rabbit Kingdom(区间更新求和)

    题目大意:给一个n个整数的数列,q次询问,每次询问区间[l,r]中与区间中其它数互质的数的个数.. 题目分析:离线处理,这里以询问区间的左端点从小到大的顺序为例.为了叙述方便,用f(l,r)表示区间[ ...

  8. 嵌入式系统Linux内核开发工程师必须掌握的三十道题(转)

    嵌入式系统Linux内核开发工程师必须掌握的三十道题 如果你能正确回答以下问题并理解相关知识点原理,那么你就可以算得上是基本合格的Linux内核开发工程师,试试看! 1) Linux中主要有哪几种内核 ...

  9. Linux应用程序的地址布局

    转载自:http://blog.csdn.net/embedded_hunter http://www.360doc.com/content/12/0405/00/1671317_200882538. ...

  10. 防止 SQL 注入的方法(摘抄)

    ——选自<深入Ajax : 架构与最佳实践 = Advanced Ajax : architecture and best practices/ (美)Shawn M.Lauriat著:张过,宋 ...