WPF中的Drawing

原文:WPF中的Drawing

以前在用WinForm的时候,可以通过GDI+接口在窗体上动态绘制自定义的图形。在WPF中有没有对应的API呢,最近项目中用到了这个,在这里总结一下。

WPF中的Drawing主要提供了几类API:

1. Drawing类型

该组类型主要用来对绘制的对象的描述。比如GeometryDrawing是描述一个几何图形的Drawing,它的Geometry属性定义了它所描述的几何图形是什么样子。(它可以是如下Geometry类型的派生类型的任何一种,GeometryGroup是对多个Geometry的组合)

与GeometryGroup一样,DrawingGroup是对多个Drawing的组合。

2. DrawingContext类型

Drawing类型是以对象的形式来描述要绘制的图形,文字或视频。DrawingContext是通过存储绘制命令的形式来对要绘制的对象进行描述。这种方式更加简单。我们可以通过DrawingGroup.Open方法来得到一个DrawingContext,然后可以调用如下接口来进行操作。

探其究竟,其实DrawingContext仅仅是将对Drawing对象的创建与管理进行了包装,然后提供了一组比较方便使用的接口而已。

看反编译出来的代码:

public override void DrawEllipse(Brush brush, Pen pen, Point center, AnimationClock centerAnimations, double radiusX, AnimationClock radiusXAnimations, double radiusY, AnimationClock radiusYAnimations)
    {
        this.VerifyApiNonstructuralChange();
        if ((brush != null) || (pen != null))
        {
            EllipseGeometry newFreezable = new EllipseGeometry(center, radiusX, radiusY) {
                CanBeInheritanceContext = this.CanBeInheritanceContext
            };
            this.SetupNewFreezable(newFreezable, ((centerAnimations == null) && (radiusXAnimations == null)) && (radiusYAnimations == null));
            if (centerAnimations != null)
            {
                newFreezable.ApplyAnimationClock(EllipseGeometry.CenterProperty, centerAnimations);
            }
            if (radiusXAnimations != null)
            {
                newFreezable.ApplyAnimationClock(EllipseGeometry.RadiusXProperty, radiusXAnimations);
            }
            if (radiusYAnimations != null)
            {
                newFreezable.ApplyAnimationClock(EllipseGeometry.RadiusYProperty, radiusYAnimations);
            }
            this.AddNewGeometryDrawing(brush, pen, newFreezable);
        }
    }

private void AddNewGeometryDrawing(Brush brush, Pen pen, Geometry geometry)
{
    GeometryDrawing newFreezable = new GeometryDrawing {
        CanBeInheritanceContext = this.CanBeInheritanceContext,
        Brush = brush,
        Pen = pen,
        Geometry = geometry
    };
    this.SetupNewFreezable(newFreezable, (((brush == null) || brush.IsFrozen) && ((pen == null) || pen.IsFrozen)) && geometry.IsFrozen);
    this.AddDrawing(newFreezable);
}

private void AddDrawing(Drawing newDrawing)
{
    if (this._rootDrawing == null)
    {
        this._rootDrawing = newDrawing;
    }
    else if (this._currentDrawingGroup == null)
    {
        this._currentDrawingGroup = new DrawingGroup();
        this._currentDrawingGroup.CanBeInheritanceContext = this.CanBeInheritanceContext;
        this.SetupNewFreezable(this._currentDrawingGroup, false);
        this._currentDrawingGroup.Children.Add(this._rootDrawing);
        this._currentDrawingGroup.Children.Add(newDrawing);
        this._rootDrawing = this._currentDrawingGroup;
    }
    else
    {
        this._currentDrawingGroup.Children.Add(newDrawing);
    }
}

3.接受Drawing作为Content的类型

可以通过这些类型来应用Drawing中描述的对象绘制。

主要有如下几种:

(1)DrawingImage,结合Image控件可以将Drawing显示在UI上

(2) DrawingBrush, 都有了Brush了,那就可以在仍何控件画了。比如说作为控件的Background.

(3) DrawingVisual类型

通过该类型,可以将Drawing创建为一个Visual.然后可以将Visual提供给一VisualContainer(可以自定义从FrameworkElement派生的类型,然后重写GetVisualChild与VisualChildrenCount方法作为VisualContainer)作为其UI呈现。

结合RenderTargetBitmap和BitmapEncoder, 我们可以将Drawing呈现到Bitmap图片文件中。

原文地址:https://www.cnblogs.com/lonelyxmas/p/10261653.html

时间: 2024-08-13 17:54:56

WPF中的Drawing的相关文章

浏览器扩展系列————在WPF中定制WebBrowser快捷菜单

原文:浏览器扩展系列----在WPF中定制WebBrowser快捷菜单 关于如何定制菜单可以参考codeproject上的这篇文章:http://www.codeproject.com/KB/books/0764549146_8.aspx?fid=13574&df=90&mpp=25&noise=3&sort=Position&view=Quick&fr=26#xx0xx 本文主要讲述如何在这篇文章中的ShowContextMenu方法中弹出自己的Conte

转载 [WPF][C#]在WPF中内嵌WindowsForm控件-使用WindowsFormsControlLibrary

[WPF][C#]在WPF中内嵌WindowsForm控件-使用WindowsFormsControlLibrary 在[WPF][C#]在WPF中内嵌WindowsForm控件一文中为各位介绍了直接在WPF中使用XAML来嵌入Windows Form控件的作法,不过不是每个人都喜欢写XAML,而且有时候会需要把已经存在的Windows Form应用程序嵌入到WPF中,所以这次就来跟大家介绍怎么使用参考dll档的方式,把dll中的Windows Form加到WPF中. 都说了要使用Windows

在WPF中使用AForge.net控制摄像头拍照

原文:在WPF中使用AForge.net控制摄像头拍照 利用AForge.net控制摄像头拍照最方便的方法就是利用PictureBox显示摄像头画面,但在WPF中不能直接使用PictureBox.必须通过<WindowsFormsHost></WindowsFormsHost>来提供交换功能.其解决方法如下: 1.按照常规方法新建一个WPF应用程序: 2.添加引用 WindowsFormsIntegration  (与WinForm交互的支持) System.Windows.For

WPF中实现验证码功能

其实和winform中的实现差不多,只是由于WPF中控件使用的库与winform中的有区别,大体上还是差不多的,直接看代码: 产生验证码的类:ValidCode.cs public class ValidCode { #region Private Fields private const double PI = 3.1415926535897932384626433832795; private const double PI2 = 6.2831853071795864769252867665

WPF 中模拟键盘和鼠标操作

转载:http://www.cnblogs.com/sixty/archive/2009/08/09/1542210.html 更多经典文章:http://www.qqpjzb.cn/65015.html 其实SendKeys类提供的方法蛮好用的,可惜的是WPF中不能用了,说是WPF的消息循环方式改成了Dispatcher,所以直接调用System.Windows.Forms.SendKeys.Send()方法会报错. 不过没关系, 至少有use32的SendInput可用,通过P/Invoke

WPF中的imagesource 和内存图片的处理

[转载]ImageSource的使用心得 很多时候,我们会使用图片来装饰UI,比如作为控件背景等. 而这些图片可以分为两种形式,即存在于本地文件系统中的图片和存在于内存中的图片 对于这两种形式的图片,在WPF中,使用方法不同,下面主要说明针对这两种形式图片的使用方法 一.存在于本地文件系统中的图片文件 对于此类图片,使用非常简单,在xaml中直接指定路径即可,如: 1<Button> 2    <Button.Background> 3        <ImageBrush 

GMap.Net解决方案之在WinForm和WPF中使用GMap.Net地图插件的开发

在做地理位置相关的开发时,总是面临高额地图引擎费用让大部分用户望而却步,加之地图数据又是天价,那么GMap.NET就是首选了,它本身就是开源免费,服务器可以在本地缓存,以后访问时就可以直接访问. 可以广泛用于保密单位的空间数据服务应用,如军队.武警.公安等保密单位.下面我们就开始我们的GMap.NET的之旅吧! 什么是GMap.NET? 来看看它的官方说明:GMap.NET is great and Powerful, Free, cross platform, open source .NET

WPF中使用Hashtable剔除重复字符串(比如电话号码)

原文:WPF中使用Hashtable剔除重复字符串(比如电话号码) 本文中的输入框中的字符串是逗号隔开的,你可以换成其他特别的字符串. 本篇中的亮点:1. 里面有一个玻璃样式按钮,用XAML制作2. WPF下TextBox允许多行文本的设置3. 使用Hashtable剔除重复字符串(比如电话号码) 运行时的样子:(为了保护隐私,做了虚化及其他处理) WPF下TextBox允许多行文本的设置:需要:(1)将TextWrapping设为"Wrap"(2)将AcceptsReturn设为&q

WPF 中的 loaded 事件和 Initialized 事件

在 WPF 中, 控件有 Loaded 和 Initialized 两种事件. 初始化和加载控件几乎同时发生, 因此这两个事件也几乎同时触发. 但是他们之间有微妙且重要的区别. 这些区别很容易让人误解. 这里介绍我们设计这些事件的背景. (不仅适用于 Control 类, 同样在通用类如 FrameworkElement 和 FrameworkContentElement 类也适用.) 下面是个小故事: Initialized 事件只说: 这个元素已经被构建出来,并且它的属性值都被设置好了,所以