在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. 08.Hibernate的一级缓存-->>Session

    Hibernate提供了两种缓存: 1.一级缓存:自带的不可卸载的,一级缓存的生命周期与Session一致,一级缓存成为Session级别的缓存 2.二级缓存:默认没有开启,需要手动配置才可以使用,二 ...

  2. Java实现数字大写转换

    需求如下:用json读取后台工时信息,比如23.5小时,需要通过编码将其转换为贰拾叁点伍 比如23.23之前有对Stringl类型强转为Double在转为整型,发生了精度丢失,后来想想对小数点进行分割 ...

  3. HZOI2019 A. 那一天我们许下约定 dp

    题目大意:https://www.cnblogs.com/Juve/articles/11219089.html 读这道题的题目让我想起了... woc我到底在想什么?好好写题解,现在不是干那个的时候 ...

  4. windows下docker 启动jenkins成功,浏览器无法访问,拒绝了我们的连接

    [问题现象] 在Windows下使用docker启动了一个jenkins,翻越了无数的坑,最后的启动命令为 docker run --name jenkins -u root -p 8000:8000 ...

  5. PipeCAD Import IDF

    PipeCAD Import IDF eryar@163.com IDF/PCF文件是国际标准管道数据交换文件,主要用于isogen生成ISO图.目前主流设计软件都可以生成这些格式的文件,如PDMS. ...

  6. 查看cpu性能和磁盘空间

    df -h查看当前磁盘空间 du -sh查看当前目录占用的磁盘空间 du -sh * 查看当前所有目录占用的磁盘空间   lscpu查看cpu信息 free查看空间总量

  7. Hadoop IO 特性详解(2)【文件校验】

    (本文引用了microheart,ggjucheng的一些资料,在此感谢.charles觉得知识无价,开源共享无价) 这一次我们接着分析文件IO校验的相关代码,看看最底层是如何实现这种大数据集的文件校 ...

  8. hdu1233还是畅通工程

    还是畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  9. Jquery 判断值是否存在于数组之内

    var strArray=str.split(","); var fixed_init=function(v){ if($.inArray(v,strArray)==-1){ // ...

  10. 组合数学起步-排列计数[ZJOI2010][BZOJ2111]

    <题面> 数据范围:$1 \leq N \leq 10^6, P \leq 10^9 $ 这个题…… 以为是排列,其实是组合 题目中说是从所有排列中找到Magic的,就是 $p_{i/2} ...