在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. 【牛客挑战赛31D】 雷的打字机

    题目 首先看到这个出现长度至少为\(2\)的回文子串 这就等价于不能出现两个连续且相同的字符 于是我们用概率生成函数来搞 设\(g_i\)表示\(i\)次操作后游戏没有结束的概率,\(f_{i,j}\ ...

  2. 1、Redis的使用

    非关系型数据库分类: 分类 典型代表 典型应用场景 数据类型 优点 缺点 键值 (key-value) Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle B ...

  3. elasticsearch river 参数文档

    JDBC River parameters Jörg Prante edited this page on 23 Jan 2014 · 3 revisions Pages 15 Home Bulk i ...

  4. Free- Linux必学的60个命令

    1.作用 free命令用来显示内存的使用情况,使用权限是所有用户. 2.格式 free [-b|-k|-m] [-o] [-s delay] [-t] [-V] 3.主要参数 -b -k -m:分别以 ...

  5. Angularjs 1 中使用指令绑定点击事件

    项目中,模板中的菜单是jQuery控制的,在Angularjs中就运行不到了,因为菜单项是ng-repeat之后的. 如html <ul id="main-menu"> ...

  6. mac上安装软件后,桌面上软件的图标如何去掉?

    桌面上的图标是软件的镜像包,默认安装以镜像形式,你选中它,按command+e 就可以推掉它

  7. Linux产生coredump文件(core)

    1.可以使用命令 ulimit -c unlimited 来开启 core dump 功能,并且不限制 core dump 文件的大小: 如果需要限制文件的大小,将 unlimited 改成你想生成 ...

  8. 阿里云HBase Ganos全新升级,推空间、时空、遥感一体化基础云服务

    1.HBase Ganos是什么 Ganos是阿里云时空PaaS服务的自研核心引擎.Ganos已作为云数据库时空引擎与数据库平台融合,建立了以自研云原生数据库POALRDB为基础,联合NoSQL大数据 ...

  9. Vue.nextTick()的介绍和使用场景

    每次都很好奇这个干嘛的,然后百度之后还是不明白.今天就彻彻底底好好的弄明白这是干嘛的!! 首先看一下vue文档 nextTick(),是将回调函数延迟在下一次DOM更新数据后调用,简单的理解是:当数据 ...

  10. 多对多关联懒加载导致failed to lazily initialize a collection of role: 实体类, could not initialize proxy - no Session 追加配置fetch = FetchType.EAGER解决

    一篇文章需要关联很多个标签,所以他们呈一对多(多对多)的关系 org.springframework.web.util.NestedServletException: Request processi ...