zoukankan      html  css  js  c++  java
  • WPF中的Drawing

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

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

    1. Drawing类型

    image

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

    image

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

    2. DrawingContext类型

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

    image

    探其究竟,其实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上

    image

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

    image

    (3) DrawingVisual类型

    image

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

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

    image

  • 相关阅读:
    Linux命令之用户与组管理
    ubantu命令安装banner
    Linux命令之必杀绝技Vi文本编辑的使用
    Linux命令初步了解
    C#中的一些技巧
    .net对文件的操作之对文件目录的操作
    Linux学习一些在Terminal可以用到的快捷键及Shell常用的通配符
    【初识】正则表达式
    .net对文件的操作之文件读写
    分享一次在Windows Server2012 R2中安装SQL Server2008
  • 原文地址:https://www.cnblogs.com/Code-life/p/3839714.html
Copyright © 2011-2022 走看看