在WPF中,如果需要绘制大量图形元素,并且对性能要求严苛的话,最好使用DrawingVisual,当然,你也可以选用

Path类和比Path类更轻量级的Geometry(几何形状)来实现你的需求,但是开销会比DrawingVisual来的大。

DrawingVisual继承自ContainerVisual,该类有一个RenderOpen方法,返回一个可用于定义可视化内容的DrawingContext对象,绘制完毕后需要调用DrawingContext.Close()方法来结束绘图。

DrawingContext中有各种绘图的方法,包括DrawLine,DrawRectangle,DrawText等等,今天我们举一个较复杂的例子DrawGeometry().

在此之前,我们需要做一些准备工作:参考自<WPF编程宝典>第三部分--图画和动画--330页

1.为元素调用AddVisualChild()和AddLogicalChild()方法来注册可视化元素

2.重写VisualChildrenCount属性和重写GetVisualChild()方法,本质上是劫持了那个元素,如果使用一些能包含控件的例如Panel,Window,则这些panel,window中除了DrawingVisual,其他的控件将不再可见。

代码如下:

 public partial class MainWindow : Window
{
private DrawingVisual _drawingVisual = new DrawingVisual();
public MainWindow()
{
InitializeComponent();
this.AddVisualChild(_drawingVisual);
var dc = _drawingVisual.RenderOpen();
PathFigure pthFigure = new PathFigure();
pthFigure.IsClosed = false; //是否封闭
pthFigure.IsFilled = false; //是否填充
pthFigure.StartPoint = new Point(10, 100); System.Windows.Point Point1 = new System.Windows.Point(10, 100);
System.Windows.Point Point2 = new System.Windows.Point(100, 200);
System.Windows.Point Point3 = new System.Windows.Point(200, 30);
System.Windows.Point Point4 = new System.Windows.Point(250, 200);
System.Windows.Point Point5 = new System.Windows.Point(200, 150); PolyLineSegment plineSeg = new PolyLineSegment();
plineSeg.Points.Add(Point1);
plineSeg.Points.Add(Point2);
plineSeg.Points.Add(Point3);
plineSeg.Points.Add(Point4);
plineSeg.Points.Add(Point5); PathSegmentCollection myPathSegmentCollection = new PathSegmentCollection();
myPathSegmentCollection.Add(plineSeg); pthFigure.Segments = myPathSegmentCollection; PathFigureCollection pthFigureCollection = new PathFigureCollection(); pthFigureCollection.Add(pthFigure); PathGeometry pthGeometry = new PathGeometry(); pthGeometry.Figures = pthFigureCollection; dc.DrawGeometry(Brushes.White, new Pen(Brushes.White,1), pthGeometry); dc.Close();
}
//必须重载这两个方法,不然是画不出来的
// 重载自己的VisualTree的孩子的个数,由于只有一个DrawingVisual,返回1
protected override int VisualChildrenCount
{
get { return 1; }
} // 重载当WPF框架向自己要孩子的时候,返回返回DrawingVisual
protected override Visual GetVisualChild(int index)
{
if (index == 0)
return _drawingVisual; throw new IndexOutOfRangeException();
}
}

WPF还为DrawingVisual提供了可以命中测试,用以实现点击,拖拽等功能,主要是依靠方法VisualTreeHelper.HitTest,

我尝试着用了下,这个方法比较消耗性能,而且只适合那种面积较大的按钮,方块,一点就中的情况,如果是一条线或者一个小点,则很难点击命中。我会建议使用Path,自带了各种鼠标事件。这个在WPF编程宝典中有详解,不再赘述!

如果既需要大量的图形,又需要能支持鼠标事件的控件,我建议的做法是,在Grid中放置Panel用于绘制DrawingVisual,然后在放置Canvas来内置各种控件。Panel和Canvas重叠起来。

未完待续。。。。。。。。

WPF DrawingVisual详解的更多相关文章

  1. WPF数据绑定详解

    元素绑定 数据绑定最简单的形式是,源对象是WPF元素而且源属性是依赖属性.依赖项属性具有内置的更改通知支持,当在源对象中改变依赖项属性的值时,会立即更新目标对相中的绑定属性. <!--Xaml程 ...

  2. WPFの触发器详解

    例子1 简单触发器Triggers——满足简答的条件,触发 <Window x:Class="Styles.SimpleTriggers" xmlns="http: ...

  3. wpf附加属性详解

    为什么使用附加属性 附加属性的一个用途是允许不同的子元素为父元素中定义的属性指定唯一的值. 此方案的一个具体应用是,让子元素通知父元素它们在用户界面 (UI) 中的呈现方式. 一个示例是 DockPa ...

  4. WPF依赖属性详解

    WPF依赖属性详解 WPF 依赖属性 英文译为 Dependency Properties,是WPF引入的一种新类型的属性,在WPF中有着极为广泛的应用,在WPF中对于WPF Dependency P ...

  5. wpf 客户端【JDAgent桌面助手】开发详解(四) popup控件的win8.0的bug

    目录区域: 业余开发的wpf 客户端终于完工了..晒晒截图 wpf 客户端[JDAgent桌面助手]开发详解-开篇 wpf 客户端[JDAgent桌面助手]详解(一)主窗口 圆形菜单... wpf 客 ...

  6. wpf 客户端【JDAgent桌面助手】开发详解(三) 瀑布流效果实现与UI虚拟化优化大数据显示

    目录区域: 业余开发的wpf 客户端终于完工了..晒晒截图 wpf 客户端[JDAgent桌面助手]开发详解-开篇 wpf 客户端[JDAgent桌面助手]详解(一)主窗口 圆形菜单... wpf 客 ...

  7. wpf中的触发器详解 (转自 乂乂的日志 - 网易博客)

    2010-03-24 16:19:07|  分类: WPF相关 |  标签: |字号大中小 订阅     wpf中的触发器详解 WPF/C# 2009-08-24 11:32:50 7.1.2  简单 ...

  8. wpf 客户端【JDAgent桌面助手】开发详解-开篇

    上周二 发表了一个帖子:wpf 客户端[JDAgent桌面助手]业余开发的终于完工了..晒晒截图... 没有想到不到一个周时间已经浏览量过8千,估计过几天就过万了..很开心啊.. 评论中好多网友问我要 ...

  9. wpf 客户端【JDAgent桌面助手】开发详解(一)主窗口 圆形菜单

    目录区域: wpf 客户端[JDAgent桌面助手]业余开发的终于完工了..晒晒截图wpf 客户端[JDAgent桌面助手]开发详解-开篇 内容区域: 这里开始主窗口 圆形菜单制作的过程,首先请大家看 ...

随机推荐

  1. List -- 列表的一些操作

    1,基本操作 2,内建函数 3,方法Method

  2. 阿里云数据库再获学术顶会认可,一文全览VLDB最新亮点

    一年一度的数据库领域顶级会议VLDB 2019于当地时间8月26日-8月30日在洛杉矶圆满落幕.在本届大会上,阿里云数据库产品团队浓墨登场,不仅有多篇论文入选Research Track和Indust ...

  3. svn 设置快捷命令

    # some more svn aliases alias svnset='svn propset svn:externals . -F' alias svnget='svn propget svn: ...

  4. 图像分割中的loss--处理数据极度不均衡的状况

    序言: 对于小目标图像分割任务,一副图画中往往只有一两个目标,这样会加大网络训练难度,一般有三种方法解决: 1.选择合适的loss,对网络进行合理优化,关注较小的目标. 2.改变网络结构,使用atte ...

  5. ie浏览器将网页转成pdf

    今天同事让我帮他将网页转成pdf,学了一个.先推荐一个超图的数据库使用指南:http://support.supermap.com.cn/DataWarehouse/WebDocHelp/6.1.1/ ...

  6. 转:fork()子进程创建

    源地址:http://blog.chinaunix.net/uid-23037385-id-2565472.html fork()子进程创建 在 UNIX 系统中,用户创建一个新进程的唯一方法就是调用 ...

  7. PAT甲级——A1022 Digital Library

    A Digital Library contains millions of books, stored according to their titles, authors, key words o ...

  8. 木卯先生的笔记---Object类

    1.简介 Object类是在 java.lang 包下的一个类,它是所有类的父类(也就是所有类都是Object类的子类,如果定义一个类的时候,没有指定继承的类,默认的就是继承Object类),所以Ob ...

  9. C#获取C# DLL中的指定接口的所有实现实例 - qq_19759475的博客 - CSDN博客

    原文:C#获取C# DLL中的指定接口的所有实现实例 - qq_19759475的博客 - CSDN博客 public static List<T> CreateTarInterface& ...

  10. webService学习五(插入片,---监控方法)

    WS Explorer工具的使用: 1- web服务浏览器 2-将对应的路径copy到这里 - 3- 4-- 5-- 6--请求的数据: 7--相应数据 二.使用TCP/IP Monitor-拦截HT ...