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

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

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

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

 protected override void OnRender(DrawingContext dc)
        {
            base.OnRender(dc);

            //public sealed class GeometryGroup : Geometry
            EllipseGeometry ellipse = new EllipseGeometry(new Point(50, 50), 50, 20);
            RectangleGeometry rect = new RectangleGeometry(new Rect(50, 50, 50, 20), 5, 5);

            GeometryGroup group = new GeometryGroup();
            group.FillRule = FillRule.EvenOdd;
            group.Children.Add(ellipse);
            group.Children.Add(rect);

            dc.DrawGeometry(Brushes.LightBlue, new Pen(Brushes.Green, 2), group);
        }

效果图如下:

我们只是简单地将两个图形以相加的方式合并在了一起,注意到合并后的图形中间部分出现一个镂空的无色区域,是由合并后的图形的FillRull决定的,如果我们把group.FillRule = FillRule.EvenOdd;更改为 group.FillRule = FillRule.Nonzero;则填充效果将是如下这样:


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

 protected override void OnRender(DrawingContext dc)
        {
            base.OnRender(dc);

            //public sealed class CombinedGeometry : Geometry
            EllipseGeometry ellipse = new EllipseGeometry(new Point(50, 50), 50, 20);
            RectangleGeometry rect = new RectangleGeometry(new Rect(50, 50, 50, 20), 5, 5);

            CombinedGeometry combin = new CombinedGeometry(GeometryCombineMode.Xor, ellipse, rect);

            dc.DrawGeometry(Brushes.LightBlue, new Pen(Brushes.Green, 2), combin);
        }

注意到GeometryCombineMode枚举,它有四个枚举值,如果我们有A,B分别表示两个图形的话,那么:
GeometryCombineMode.Exclude:  合并结果为A-B

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

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

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

3, 使用Geometry.Combin()静态方法进行图形合并
Geometry.Combin()静态方法与使用CombinedGeometry对象进行图形合并差不多

 protected override void OnRender(DrawingContext dc)
        {
            base.OnRender(dc);


            //Geometry.Combin()
            EllipseGeometry ellipse = new EllipseGeometry(new Point(50, 50), 50, 20);
            RectangleGeometry rect = new RectangleGeometry(new Rect(50, 50, 50, 20), 5, 5);

            PathGeometry combin = Geometry.Combine(ellipse, rect, GeometryCombineMode.Xor, null);

            dc.DrawGeometry(Brushes.LightBlue, new Pen(Brushes.Green, 2), combin);

        }

其中Geometry.Combin()静态方法中有用于图形变换的参数(旋转,缩放等),如果不需要变换则填写null

在WPF中自定义你的绘制(三)的更多相关文章

  1. 在WPF中自定义你的绘制(二)

    原文:在WPF中自定义你的绘制(二)   在WPF中自定义你的绘制(二)                                                                 ...

  2. 在WPF中自定义你的绘制(五)

    原文:在WPF中自定义你的绘制(五) 在WPF中自定义你的绘制(五)                                                                   ...

  3. 在WPF中自定义你的绘制(四)

    原文:在WPF中自定义你的绘制(四)                                   在WPF中自定义你的绘制(四)                                 ...

  4. 在WPF中自定义你的绘制(一)

    原文:在WPF中自定义你的绘制(一)   在WPF中自定义你的绘制(一)                                                                 ...

  5. 在VS2005中设置WPF中自定义按钮的事件

    原文:在VS2005中设置WPF中自定义按钮的事件 上篇讲了如何在Blend中绘制圆角矩形(http://blog.csdn.net/johnsuna/archive/2007/08/13/17407 ...

  6. WPF中自定义的DataTemplate中的控件,在Window_Loaded事件中加载机制初探

    原文:WPF中自定义的DataTemplate中的控件,在Window_Loaded事件中加载机制初探         最近因为项目需要,开始学习如何使用WPF开发桌面程序.使用WPF一段时间之后,感 ...

  7. 示例:WPF中自定义MessageService应用DialogHost、Snackbar、NotifyIcon显示各种场景提示消息

    原文:示例:WPF中自定义MessageService应用DialogHost.Snackbar.NotifyIcon显示各种场景提示消息 一.目的:不同交互场景需要提示不同的消息,不同的消息需要用不 ...

  8. 示例:WPF中自定义StoryBoarService在代码中封装StoryBoard、Animation用于简化动画编写

    原文:示例:WPF中自定义StoryBoarService在代码中封装StoryBoard.Animation用于简化动画编写 一.目的:通过对StoryBoard和Animation的封装来简化动画 ...

  9. WPF中自定义绘制内容

    先说结论:实现了在自定义大小的窗口中,加载图片,并在图片上绘制一个矩形框:且在窗口大小改变的情况,保持绘制的矩形框与图片的先对位置不变. 在WinForm中,我们可以很方便地绘制自己需要的内容,在WP ...

随机推荐

  1. BufferedStream类 - 缓冲流

    BufferedStream常用于对其他流的一个封装,它必须和其他流结合一起使用.MemoryStream将所有的内容都放入内存中,而BufferedStream不是.BufferedStream在基 ...

  2. 剑指offer-面试题6.重建二叉树

    题目:输入某二叉树的前序遍历和中序遍历结果,请重建出该二叉树.假设 输入的前序遍历和中序遍历的结果都不含重复的数字.例如输入前序遍历 序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2, ...

  3. Qt Creator编译时:cannot open file 'debug\QtGuiEx.exe' File not found

    Qt Creator编译时:cannot open file 'debug\QtGuiEx.exe' File not found 利用Qt Creator编译工程时,出现如题目所示的错误,其中红色部 ...

  4. 【C++基础之十四】函参的缺省

    可能会有这么一个函数,在大部分的情况下,我们不用给它传递参数,但在某些特殊情况下,我们需要给它传递参数,那怎么办呢? 简单啊,写两个一样的方法,一个带参,一个不带参... 这样也太没水准了.来点高端的 ...

  5. linux 有名管道(FIFO)

    http://blog.csdn.net/firefoxbug/article/details/8137762 linux 有名管道(FIFO) 管道的缓冲区是有限的(管道制存在于内存中,在管道创建时 ...

  6. 【转】Android LCD(三):Samsung LCD接口篇

    关键词:android LCD控制器 Framebuffer PWM  平台信息:内核:linux2.6/linux3.0系统:android/android4.0 平台:samsung exynos ...

  7. Segment(技巧 相乘转换成相加 + java)

     Segment Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Sta ...

  8. 如何煉成NET架構師

    微软的DotNet 开发绝对是属于那种入门容易提高难的技术.而要能够成为DotNet 架构师没有三年或更长时间的编码积累基本上是不可能的.特别是在大型软件项目中,架构师是项目核心成员,承上启下,因此 ...

  9. error: ‘for’ loop initial declarations are only allowed in

    使用gcc,出现如下错误: thread_join.c:7:5: error: 'for' loop initial declarations are only allowed in C99 mode ...

  10. sybase用户管理(创建、授权、删除)

    一.登录用户管理:1.创建用户:sp_addlogin loginame, passwd [, defdb] [, deflanguage] [, fullname] [, passwdexp] [, ...