在WPF中自定义你的绘制(三)

简介: 原文:在WPF中自定义你的绘制(三)                                             在WPF中自定义你的绘制(三)                                                                  周银辉图形合并有时候我们需要将多个图形合并成一个然后进行绘制,比如将一个圆形与一个矩形进行合并等. 在WPF的自定义绘制中,有三种方法可以做到,分别是(1)利用GeometryGroup对象;(2)利用CombinedGeometry对象;(3)使用Geometry.Combin()静态方法。
原文: 在WPF中自定义你的绘制(三)

                                             在WPF中自定义你的绘制(三)
                                                                  周银辉

图形合并
有时候我们需要将多个图形合并成一个然后进行绘制,比如将一个圆形与一个矩形进行合并等. 在WPF的自定义绘制中,有三种方法可以做到,分别是(1)利用GeometryGroup对象;(2)利用CombinedGeometry对象;(3)使用Geometry.Combin()静态方法。其中第一种方式是利用集合并可以向集合中添加任意多个元素,而后面两种方式只能两两合并,但后面两者的合并方式更灵活,可以是两图形的“交集”“并集”“差集”以及“异或”。

1 ,使用GeometryGroup对象进行图形合并
参考以下代码,我们合并了一个椭圆与一个矩形:

img_a6339ee3e57d1d52bc7d02b338e15a60.gif   protected   override   void  OnRender(DrawingContext dc)
img_405b18b4b6584ae338e0f6ecaf736533.gifimg_1c53668bcee393edac0d7b3b3daff1ae.gif        
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif {
img_33d02437d135341f0800e3d415312ae8.gif            
base.OnRender(dc);
img_33d02437d135341f0800e3d415312ae8.gif
img_33d02437d135341f0800e3d415312ae8.gif            
//public sealed class GeometryGroup : Geometry
img_33d02437d135341f0800e3d415312ae8.gif
            EllipseGeometry ellipse = new EllipseGeometry(new Point(5050), 5020);
img_33d02437d135341f0800e3d415312ae8.gif            RectangleGeometry rect 
= new RectangleGeometry(new Rect(50505020), 55);
img_33d02437d135341f0800e3d415312ae8.gif
img_33d02437d135341f0800e3d415312ae8.gif            GeometryGroup group 
= new GeometryGroup();
img_33d02437d135341f0800e3d415312ae8.gif            group.FillRule 
= FillRule.EvenOdd;
img_33d02437d135341f0800e3d415312ae8.gif            group.Children.Add(ellipse);
img_33d02437d135341f0800e3d415312ae8.gif            group.Children.Add(rect);
img_33d02437d135341f0800e3d415312ae8.gif
img_33d02437d135341f0800e3d415312ae8.gif            dc.DrawGeometry(Brushes.LightBlue, 
new Pen(Brushes.Green, 2), group);
img_05dd8d549cff04457a6366b0a7c9352a.gif        }
效果图如下:
customPaint_GeometryGroup1.png
我们只是简单地将两个图形以相加的方式合并在了一起,注意到合并后的图形中间部分出现一个镂空的无色区域,是由合并后的图形的FillRull决定的,如果我们把group.FillRule = FillRule.EvenOdd;更改为 group.FillRule = FillRule.Nonzero;则填充效果将是如下这样:
customPaint_GeometryGroup2.png


2, 使用CombinedGeometry对象进行图形合并
参考以下代码,我们合并了一个椭圆与一个矩形:
img_a6339ee3e57d1d52bc7d02b338e15a60.gif   protected   override   void  OnRender(DrawingContext dc)
img_405b18b4b6584ae338e0f6ecaf736533.gifimg_1c53668bcee393edac0d7b3b3daff1ae.gif        
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif {
img_33d02437d135341f0800e3d415312ae8.gif            
base.OnRender(dc);
img_33d02437d135341f0800e3d415312ae8.gif
img_33d02437d135341f0800e3d415312ae8.gif            
//public sealed class CombinedGeometry : Geometry
img_33d02437d135341f0800e3d415312ae8.gif
            EllipseGeometry ellipse = new EllipseGeometry(new Point(5050), 5020);
img_33d02437d135341f0800e3d415312ae8.gif            RectangleGeometry rect 
= new RectangleGeometry(new Rect(50505020), 55);
img_33d02437d135341f0800e3d415312ae8.gif
img_33d02437d135341f0800e3d415312ae8.gif            CombinedGeometry combin 
= new CombinedGeometry(GeometryCombineMode.Xor, ellipse, rect);
img_33d02437d135341f0800e3d415312ae8.gif
img_33d02437d135341f0800e3d415312ae8.gif            dc.DrawGeometry(Brushes.LightBlue, 
new Pen(Brushes.Green, 2), combin);
img_05dd8d549cff04457a6366b0a7c9352a.gif        }
注意到GeometryCombineMode枚举,它有四个枚举值,如果我们有A,B分别表示两个图形的话,那么:
GeometryCombineMode.Exclude:  合并结果为A-B customPaint_CombinedGeometry_Exclude.png

GeometryCombineMode.Intersect:  合并结果为A与B的相交部分 customPaint_CombinedGeometry_Intersect.png

GeometryCombineMode.Union:  合并结果为A+B customPaint_CombinedGeometry_Union.png

GeometryCombineMode.Xor:  合并结果为(A-B)+(B-A) customPaint_CombinedGeometry_Xor.png

3, 使用Geometry.Combin()静态方法进行图形合并
Geometry.Combin()静态方法与使用CombinedGeometry对象进行图形合并差不多
img_a6339ee3e57d1d52bc7d02b338e15a60.gif   protected   override   void  OnRender(DrawingContext dc)
img_405b18b4b6584ae338e0f6ecaf736533.gifimg_1c53668bcee393edac0d7b3b3daff1ae.gif        
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif {
img_33d02437d135341f0800e3d415312ae8.gif            
base.OnRender(dc);
img_33d02437d135341f0800e3d415312ae8.gif
img_33d02437d135341f0800e3d415312ae8.gif
img_33d02437d135341f0800e3d415312ae8.gif            
//Geometry.Combin()
img_33d02437d135341f0800e3d415312ae8.gif
            EllipseGeometry ellipse = new EllipseGeometry(new Point(5050), 5020);
img_33d02437d135341f0800e3d415312ae8.gif            RectangleGeometry rect 
= new RectangleGeometry(new Rect(50505020), 55);
img_33d02437d135341f0800e3d415312ae8.gif
img_33d02437d135341f0800e3d415312ae8.gif            PathGeometry combin 
= Geometry.Combine(ellipse, rect, GeometryCombineMode.Xor, null);
img_33d02437d135341f0800e3d415312ae8.gif
img_33d02437d135341f0800e3d415312ae8.gif            dc.DrawGeometry(Brushes.LightBlue, 
new Pen(Brushes.Green, 2), combin);
img_33d02437d135341f0800e3d415312ae8.gif
img_05dd8d549cff04457a6366b0a7c9352a.gif        }
其中Geometry.Combin()静态方法中有用于图形变换的参数(旋转,缩放等),如果不需要变换则填写null





目录
相关文章
|
C# 虚拟化 索引
【WPF】UI虚拟化之------自定义VirtualizingWrapPanel
原文:【WPF】UI虚拟化之------自定义VirtualizingWrapPanel 前言 前几天QA报了一个关于OOM的bug,在排查的过程中发现,ListBox控件中被塞入了过多的Item,而ListBox又定义了两种样式的ItemsPanelTemplate。
2016 0
|
C# 数据安全/隐私保护
【WPF】右下角弹出自定义通知样式(Notification)——简单教程
原文:【WPF】右下角弹出自定义通知样式(Notification)——简单教程 1.先看效果 2.实现 1.主界面是MainWindow 上面就只摆放一个Button即可。
2807 0
|
前端开发 C# 图形学
【WPF】WPF开发用户控件、用户控件属性依赖DependencyProperty实现双向绑定、以及自定义实现Command双向绑定功能演示
Wpf开发过程中,最经常使用的功能之一,就是用户控件(UserControl)了。用户控件可以用于开发用户自己的控件进行使用,甚至可以用于打造一套属于自己的UI框架。依赖属性(DependencyProperty)是为用户控件提供可支持双向绑定的必备技巧之一,同样用处也非常广泛。
778 0
【WPF】WPF开发用户控件、用户控件属性依赖DependencyProperty实现双向绑定、以及自定义实现Command双向绑定功能演示
|
C#
WPF 控件自定义背景
<!--控件要设置尺寸的话,设置的尺寸必须比下面的图形的尺寸要小,不然显示不开--> <Label Content="直角测试" Width="90" Height="90" HorizontalContentAlignment="Center" Vert...
983 0
|
C#
WPF开发-Label自定义背景-Decorator
首先在App.xaml文件当中添加样式和模板
1957 0
|
C#
wpf 开发 -TextBox背景自定义-Decorator
首先在app.xaml文件的下面添加以下样式
1629 0
|
C# 前端开发
[原译]WPF绘制圆角多边形
原文:[原译]WPF绘制圆角多边形 介绍 最近,我发现我需要个圆角多边形。而且是需要在运行时从用户界面来绘制。WPF有多边形。但是不支持圆角。我搜索了一下。也没找到可行的现成例子。于是就自己做吧。本文描述了圆角多边形的实现,也包括如何用在你的项目里。
1467 0
|
C#
WPF自定义窗口最大化显示任务栏
原文:WPF自定义窗口最大化显示任务栏 当我们要自定义WPF窗口样式时,通常是采用设计窗口的属性 WindowStyle="None" ,然后为窗口自定义放大,缩小,关闭按钮的样式。 然而这样的话,当通过代码设置窗口(代码如下)放大时,窗口会把任务栏给遮档住。
1185 0
|
.NET C# Windows
WPF 自定义路由事件
原文:WPF 自定义路由事件 WPF中的路由事件 as U know,和以前Windows消息事件区别不再多讲,这篇博文中,将首先回顾下WPF内置的路由事件的用法,然后在此基础上自定义一个路由事件。 1.WPF内置路由事件   WPF中的大多数事件都是路由事件,WPF有3中路由策略: 具体不多讲,单需要注意的是WPF路由事件是沿着VIsualTree传递的。
1107 0
|
C# 前端开发
【C#】wpf自定义calendar日期选择控件的样式
原文:【C#】wpf自定义calendar日期选择控件的样式 首先上图看下样式 原理 总览 ItemsControl内容的生成 实现 界面的实现 后台ViewModel的实现 首先上图,看下样式 原理 1. 总览: Calendar本质上是一个6x7的列表,这个列表可以用ItemsControl来实现。
1087 0