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

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

将我们的绘制转变为画刷

WPF中的画刷比GDI+中要强大得多,除了常用的实心画刷、渐变画刷外,还支持更多的平铺画刷,这包括DrawingBrush、ImageBrush、VisualBrush,其中DrawingBrush使得我们可以将自定义的绘制用于任何可以使用普通画刷的地方。
比如下面的代码,我们将自定义一个椭圆和一个矩形,然后将它们合并成一个图形并将

改图形用作窗口的背景画刷:

public Window1()
        {
            InitializeComponent();


            //background
            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);
            GeometryDrawing drawing = new GeometryDrawing(Brushes.LightBlue, new Pen(Brushes.Green, 2), combin);

            DrawingBrush background = new DrawingBrush(drawing);
            this.Background = background;


        }

运行效果如下:


也许将整个图形填充于整个区域并不是我们想要的结果,没关系,我们可以通过设置视口(Viewport)和平铺方式(TileMode)来调整图形的平铺效果。

Viewport为我们指示了如何将图形投射到绘制表面,如果我们将绘制表面的左上角定义为(0,0),右下角定义我(1,1),那么可以设置一个相当与该值的矩形(Rect)来指示我们的图形应该被投射到哪里。比如Rect(0,0,0.5,0.5)则表示在绘制表面的左上角开始的长宽均为绘制表面1/2的矩形区域。这样的矩形Rect(0,0,0.5,0.5)就是我们所说的视口(这与3D中的视口类似)。所以要得到上图的效果,我们只需要这样设置我们的DrawingBrush就可以了:

background.Viewport = new Rect(0, 0, 0.15, 0.15);
background.TileMode = TileMode.Tile;

此外,DrawingBrush还有一个很有意思的属性ViewBox(继承于TileBrush),它指示了只取图形中的哪一部分作为观察区域(这与Clip不同),它的定义方式与Viewport类似,但它不是相对于绘制表面而是相当于我们的图形的。
SDK中是这样解释ViewBox的:

参考下面的代码,我们仅仅取了整个绘制的图形的1/4(整个图形的左下部分)并将其作为窗口的的背景画刷:

 public Window1()
        {
            InitializeComponent();


            //background
            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);
            GeometryDrawing drawing = new GeometryDrawing(Brushes.LightBlue, new Pen(Brushes.Green, 2), combin);

            DrawingBrush background = new DrawingBrush(drawing);
            background.Viewbox = new Rect(0.5, 0.5, 0.5, 0.5);
            this.Background = background;


        }

效果图如下:

此外,值得一提的是,Viewport和Viewbox除了使用相对值外,你也可以使用绝对坐标值,不过你需要将ViewportUnits属性和ViewboxUnit属性由BrushMappingMode.RelativeToBoundingBox修改为BrshMappingMode.Absolute。

在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. 从客户端(******)中检测到有潜在危险的 Request.Form 值。

    在 提交表单时候,asp.net 提示:"从客户端(......)中检测到有潜在危险的 Request.Form 值" .asp.net中的请求验证特性提供了某一等级的保护措施防止 ...

  2. sql server 表连接

    本文主要列举两张和三张表来讲述多表连接查询. 新建两张表: 表1:student 截图如下: SQL多表连接查询(详细实例)_新客网 表2:course 截图如下: SQL多表连接查询(详细实例)_新 ...

  3. 常用两种数据交换格式之XML和JSON的比较

    目前,在web开发领域,主要的数据交换格式有XML和JSON,对于XML相信每一个web developer都不会感到陌生: 相比之下,JSON可能对于一些新步入开发领域的新手会感到有些陌生,也可能你 ...

  4. JS 输出对象的属性以及方法[转载]

    <script>var obj  = {attribute:1,method:function() {alert("我是函数");}}for (var i in obj ...

  5. C++ Primer day 01

    1.标准输入与输出 #include<iostream> int main(){ int v1,v2; std::cout<<"Enter two numbers:& ...

  6. poj 3318 Matrix Multiplication

    http://poj.org/problem?id=3318 矩阵A*矩阵B是否等于矩阵C #include <cstdio> #include <cstring> #incl ...

  7. USB枚举过程的详细流程

    USB枚举过程的详细流程 用户将一个USB设备插入USB端口,主机为端口供电,设备此时处于上电状态.主机检测设备.1>Hub使用中断通道将事件报告给Host.2>Host发送Get_Por ...

  8. 学习笔记之--Navicat Premium创建数据表

    1.打开Navicat Premium,点击连接,选择MySQL,创建新连接.输入安装MySQL是的用户名和密码.点击确定. 2.admin数据连接已经创建成功.下面为admin新建数据库,输入数据库 ...

  9. 剑指offer-面试题5.从尾到头打印链表

    题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值. 刚看到这道题的小伙伴可能就会想,这还不简单,将链表反转输出. 但是这种情况破坏了链表的结构. 如果面试官要求不破坏链表结构呢,这时候我们 ...

  10. Unity 两张背景的切换平移

    两张背景图片向左移动,当屏幕看见的时候. 使用的是Unity自带的Sprite,当然也可以使用NGUI Sprite using UnityEngine; using System.Collectio ...