WPF DrawingVisual详解
在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详解的更多相关文章
- WPF数据绑定详解
元素绑定 数据绑定最简单的形式是,源对象是WPF元素而且源属性是依赖属性.依赖项属性具有内置的更改通知支持,当在源对象中改变依赖项属性的值时,会立即更新目标对相中的绑定属性. <!--Xaml程 ...
- WPFの触发器详解
例子1 简单触发器Triggers——满足简答的条件,触发 <Window x:Class="Styles.SimpleTriggers" xmlns="http: ...
- wpf附加属性详解
为什么使用附加属性 附加属性的一个用途是允许不同的子元素为父元素中定义的属性指定唯一的值. 此方案的一个具体应用是,让子元素通知父元素它们在用户界面 (UI) 中的呈现方式. 一个示例是 DockPa ...
- WPF依赖属性详解
WPF依赖属性详解 WPF 依赖属性 英文译为 Dependency Properties,是WPF引入的一种新类型的属性,在WPF中有着极为广泛的应用,在WPF中对于WPF Dependency P ...
- wpf 客户端【JDAgent桌面助手】开发详解(四) popup控件的win8.0的bug
目录区域: 业余开发的wpf 客户端终于完工了..晒晒截图 wpf 客户端[JDAgent桌面助手]开发详解-开篇 wpf 客户端[JDAgent桌面助手]详解(一)主窗口 圆形菜单... wpf 客 ...
- wpf 客户端【JDAgent桌面助手】开发详解(三) 瀑布流效果实现与UI虚拟化优化大数据显示
目录区域: 业余开发的wpf 客户端终于完工了..晒晒截图 wpf 客户端[JDAgent桌面助手]开发详解-开篇 wpf 客户端[JDAgent桌面助手]详解(一)主窗口 圆形菜单... wpf 客 ...
- wpf中的触发器详解 (转自 乂乂的日志 - 网易博客)
2010-03-24 16:19:07| 分类: WPF相关 | 标签: |字号大中小 订阅 wpf中的触发器详解 WPF/C# 2009-08-24 11:32:50 7.1.2 简单 ...
- wpf 客户端【JDAgent桌面助手】开发详解-开篇
上周二 发表了一个帖子:wpf 客户端[JDAgent桌面助手]业余开发的终于完工了..晒晒截图... 没有想到不到一个周时间已经浏览量过8千,估计过几天就过万了..很开心啊.. 评论中好多网友问我要 ...
- wpf 客户端【JDAgent桌面助手】开发详解(一)主窗口 圆形菜单
目录区域: wpf 客户端[JDAgent桌面助手]业余开发的终于完工了..晒晒截图wpf 客户端[JDAgent桌面助手]开发详解-开篇 内容区域: 这里开始主窗口 圆形菜单制作的过程,首先请大家看 ...
随机推荐
- python3-常用模块之序列化
序列化 : 把其他的数据类型转换成 字符串或者bytes 序列 : 列表.元组.字符串.bytes 为什么要把其他数据类型转换成字符串? 能够在网络上传输的只能是bytes,能够存储在文件里的只有by ...
- VS2010编译的时候出现fatal error LNK1146: 没有用选项“/out:”指定的参数
最近安装了下vs2010,发现对硬件要求还是很高的,先是在一个一般台式机上安装出现字体发虚的问题,操作系统也是vista sp2,尝试了网上若干方法还是发虚,总结就是硬件的显卡不行,3年前的机器了:遂 ...
- hadoop settings
ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys expor ...
- js如何往数组Array中添加元素 (2013-09-04 10
unshift:将参数添加到原数组开头,并返回数组的长度 pop:删除原数组最后一项,并返回删除元素的值:如果数组为空则返回undefined push:将参数添加到原数组末尾,并返回数组的长度 co ...
- double转integer
double id0 = row.getCell(0).getNumericCellValue(); Integer id = Integer.valueOf(Double.valueOf(id0). ...
- 7.Spring切入点的表达式和通知类型
1.切入点的表达式 表达式格式: execution([修饰符] 返回值类型 包名.类名.方法名(参数)) 其他的代替: <!-- 完全指定一个方法 --> <!-- <aop ...
- JZOJ5966【NOIP2018提高组D2T3】保卫王国(并查集)
题目 还是懒得把题目放上来了. 大意:给你一棵带点权的树,你要花费一些代价选择一些点使得相邻的两个点至少有一个被选. 然后有很多个询问,每个询问强制两个点的状态,问强制了这两个点的状态后的方案. 比赛 ...
- springcloud之配置中心用法
一.配置文件服务器server端 1.构建server端所需jar <dependencies> <dependency> <groupId>org.springf ...
- HZOI20190818模拟25题解
题面:https://www.cnblogs.com/Juve/articles/11372379.html A:字符串 其实是CATALAN数水题... 和网格一毛一样:https://www.cn ...
- SQL Server 2008 分区函数和分区表
当我们数据量比较大的时候,我们需要将大型表拆分为多个较小的表,则只访问部门数据的查询就可以更快的运行,基本原理就是,因为要扫描的数据变的更小.维护任务(例如,重新生成索引或备份表)也可以更快的运行 ...