绘图对象概述

本主题介绍 Drawing 对象,并介绍如何使用它们有效地绘制形状、位图、文本和媒体。 使用Drawing对象创建剪贴画、使用DrawingBrush绘画或使用Visual对象。

什么是绘图对象

对象 Drawing 描述可见内容,如形状、位图、视频或文本行。 不同类型的绘图描述了不同类型的内容。 下面是不同类型的绘图对象的列表。

Drawing 对象多才多艺;有多种方法可以使用 Drawing 对象。

WPF 提供能够绘制形状、位图、文本和媒体的其他类型的对象。 例如,还可以使用 Shape 对象绘制形状,并且控件 MediaElement 提供了向应用程序添加视频的另一种方法。 那么,何时应使用 Drawing 对象? 当可以牺牲框架级别功能以获得性能优势或需要 Freezable 功能时。 由于 Drawing 对象缺乏对 布局、输入和焦点的支持,因此它们提供性能优势,使它们非常适合描述背景、剪贴画,以及使用 Visual 对象的低级别绘图。

由于它们是一个类型 Freezable 对象, Drawing 因此对象将获得多个特殊功能,其中包括:它们可以声明为 资源,在多个对象之间共享,进行只读,以提高性能、克隆和使线程安全。 有关 Freezable 对象所提供的各种功能的更多信息,请参阅 Freezable 对象概述

绘制形状

若要绘制形状,请使用一个 GeometryDrawing。 几何图形 Geometry 的属性描述要绘制的形状,其 Brush 属性描述如何绘制形状的内部,其 Pen 属性描述其轮廓的绘制方式。

下面的示例使用一个 GeometryDrawing 绘制形状。 形状由一个GeometryGroup和两个EllipseGeometry对象描述。 形状的内部涂有一个 LinearGradientBrush ,其轮廓用一个 BlackPen绘制。

此示例创建以下内容 GeometryDrawing

两个椭圆的 GeometryDrawing
一个 GeometryDrawing

//
// Create the Geometry to draw.
//
GeometryGroup ellipses = new GeometryGroup();
ellipses.Children.Add(
    new EllipseGeometry(new Point(50,50), 45, 20)
    );
ellipses.Children.Add(
    new EllipseGeometry(new Point(50, 50), 20, 45)
    );

//
// Create a GeometryDrawing.
//
GeometryDrawing aGeometryDrawing = new GeometryDrawing();
aGeometryDrawing.Geometry = ellipses;

// Paint the drawing with a gradient.
aGeometryDrawing.Brush =
    new LinearGradientBrush(
        Colors.Blue,
        Color.FromRgb(204,204,255),
        new Point(0,0),
        new Point(1,1));

// Outline the drawing with a solid color.
aGeometryDrawing.Pen = new Pen(Brushes.Black, 10);
<GeometryDrawing>
  <GeometryDrawing.Geometry>

    <!-- Create a composite shape. -->
    <GeometryGroup>
      <EllipseGeometry Center="50,50" RadiusX="45" RadiusY="20" />
      <EllipseGeometry Center="50,50" RadiusX="20" RadiusY="45" />
    </GeometryGroup>
  </GeometryDrawing.Geometry>
  <GeometryDrawing.Brush>

    <!-- Paint the drawing with a gradient. -->
    <LinearGradientBrush>
      <GradientStop Offset="0.0" Color="Blue" />
      <GradientStop Offset="1.0" Color="#CCCCFF" />
    </LinearGradientBrush>
  </GeometryDrawing.Brush>
  <GeometryDrawing.Pen>

    <!-- Outline the drawing with a solid color. -->
    <Pen Thickness="10" Brush="Black" />
  </GeometryDrawing.Pen>
</GeometryDrawing>

有关完整示例,请参阅 “创建 GeometryDrawing”。

其他 Geometry 类,例如 PathGeometry ,通过创建曲线和弧线,可以创建更复杂的形状。 有关Geometry对象的详细信息,请参阅Geometry 概述

有关绘制不使用 Drawing 对象的形状的其他方法的详细信息,请参阅 WPF 概述中的形状和基本绘图

绘制图像

若要绘制图像,请使用ImageDrawing。 对象的ImageDrawingImageSource属性描述要绘制的图像,其Rect属性定义绘制图像的区域。

以下示例将在位于 (75,75) 的矩形中绘制一个 100 x 100 像素的图像。 下图展示了由示例创建的ImageDrawing。 添加了灰色边框以显示ImageDrawing的边界。

100 x 100 图像绘制在 (75,75)
100 乘 100 图像绘制

// Create a 100 by 100 image with an upper-left point of (75,75).
ImageDrawing bigKiwi = new ImageDrawing();
bigKiwi.Rect = new Rect(75, 75, 100, 100);
bigKiwi.ImageSource = new BitmapImage(
    new Uri(@"sampleImages\kiwi.png", UriKind.Relative));
<!-- The Rect property specifies that the image only fill a 100 by 100
     rectangular area. -->
<ImageDrawing Rect="75,75,100,100" ImageSource="sampleImages\kiwi.png"/>

有关图像的详细信息,请参阅 映像概述

媒体播放(仅限代码)

注释

虽然可以在可扩展应用程序标记语言(XAML)中声明VideoDrawing,但要加载和播放其媒体只能通过使用代码实现。 若要在可扩展应用程序标记语言(XAML)中播放视频,请改用 MediaElement

若要播放音频或视频文件,请使用 a VideoDrawing 和 a MediaPlayer. 有两种方法可以加载和播放媒体。 第一种方法是自行使用 MediaPlayerVideoDrawing,第二种方法是创建自己的 MediaTimelineMediaPlayerVideoDrawing 搭配使用。

注释

使用应用程序分发媒体时,不能将媒体文件用作项目资源,就像图像一样。 在项目文件中,您必须将媒体类型设置为Content,并将CopyToOutputDirectory设置为PreserveNewestAlways

若要在不创建自己的 MediaTimeline媒体的情况下播放媒体,请执行以下步骤。

  1. 创建 MediaPlayer 对象。

    MediaPlayer player = new MediaPlayer();
    
  2. 使用该方法 Open 加载媒体文件。

    player.Open(new Uri(@"sampleMedia\xbox.wmv", UriKind.Relative));
    
  3. 创建一个 VideoDrawing

    VideoDrawing aVideoDrawing = new VideoDrawing();
    
  4. 通过设置RectVideoDrawing的属性,指定绘制媒体的大小和位置。

    aVideoDrawing.Rect = new Rect(0, 0, 100, 100);
    
  5. 设置VideoDrawingPlayer属性为您创建的MediaPlayer

    aVideoDrawing.Player = player;
    
  6. 使用MediaPlayer的方法Play来开始播放媒体。

    // Play the video once.
    player.Play();
    

以下示例使用VideoDrawingMediaPlayer来播放一次视频文件。

//
// Create a VideoDrawing.
//
MediaPlayer player = new MediaPlayer();

player.Open(new Uri(@"sampleMedia\xbox.wmv", UriKind.Relative));

VideoDrawing aVideoDrawing = new VideoDrawing();

aVideoDrawing.Rect = new Rect(0, 0, 100, 100);

aVideoDrawing.Player = player;

// Play the video once.
player.Play();

若要获取对媒体的附加计时控制,请使用MediaTimelineMediaPlayerVideoDrawing对象。 您可以使用 MediaTimeline 来指定视频是否应该重复。 若要使用 a MediaTimeline 和 a VideoDrawing,请执行以下步骤:

  1. 声明MediaTimeline并设置其计时行为。

    // Create a MediaTimeline.
    MediaTimeline mTimeline =
        new MediaTimeline(new Uri(@"sampleMedia\xbox.wmv", UriKind.Relative));
    
    // Set the timeline to repeat.
    mTimeline.RepeatBehavior = RepeatBehavior.Forever;
    
  2. MediaTimeline 创建一个 MediaClock

    // Create a clock from the MediaTimeline.
    MediaClock mClock = mTimeline.CreateClock();
    
  3. 使用MediaPlayer并通过MediaClock设置Clock属性。

    MediaPlayer repeatingVideoDrawingPlayer = new MediaPlayer();
    repeatingVideoDrawingPlayer.Clock = mClock;
    
  4. 创建VideoDrawing,并将MediaPlayer分配给VideoDrawingPlayer属性。

    VideoDrawing repeatingVideoDrawing = new VideoDrawing();
    repeatingVideoDrawing.Rect = new Rect(150, 0, 100, 100);
    repeatingVideoDrawing.Player = repeatingVideoDrawingPlayer;
    

以下示例使用 MediaTimelineMediaPlayerVideoDrawing 重复播放视频。

//
// Create a VideoDrawing that repeats.
//

// Create a MediaTimeline.
MediaTimeline mTimeline =
    new MediaTimeline(new Uri(@"sampleMedia\xbox.wmv", UriKind.Relative));

// Set the timeline to repeat.
mTimeline.RepeatBehavior = RepeatBehavior.Forever;

// Create a clock from the MediaTimeline.
MediaClock mClock = mTimeline.CreateClock();

MediaPlayer repeatingVideoDrawingPlayer = new MediaPlayer();
repeatingVideoDrawingPlayer.Clock = mClock;

VideoDrawing repeatingVideoDrawing = new VideoDrawing();
repeatingVideoDrawing.Rect = new Rect(150, 0, 100, 100);
repeatingVideoDrawing.Player = repeatingVideoDrawingPlayer;

请注意,在使用MediaTimeline时,您是通过MediaClockController属性返回的交互式ClockController来控制媒体播放,而不是通过MediaPlayer的交互方法进行控制。

绘制文本

若要绘制文本,请使用 a GlyphRunDrawing 和 a GlyphRun. 下面的示例使用 a GlyphRunDrawing 绘制文本“Hello World”。

GlyphRun theGlyphRun = new GlyphRun(
    new GlyphTypeface(new Uri(@"C:\WINDOWS\Fonts\TIMES.TTF")),
    0,
    false,
    13.333333333333334,
    new ushort[]{43, 72, 79, 79, 82, 3, 58, 82, 85, 79, 71},
    new Point(0, 12.29),
    new double[]{
        9.62666666666667, 7.41333333333333, 2.96,
        2.96, 7.41333333333333, 3.70666666666667,
        12.5866666666667, 7.41333333333333,
        4.44, 2.96, 7.41333333333333},
    null,
    null,
    null,
    null,
    null,
    null

    );

GlyphRunDrawing gDrawing = new GlyphRunDrawing(Brushes.Black, theGlyphRun);
<GlyphRunDrawing ForegroundBrush="Black">
  <GlyphRunDrawing.GlyphRun>
    <GlyphRun 
      CaretStops="{x:Null}" 
      ClusterMap="{x:Null}" 
      IsSideways="False" 
      GlyphOffsets="{x:Null}" 
      GlyphIndices="43 72 79 79 82 3 58 82 85 79 71" 
      BaselineOrigin="0,12.29"  
      FontRenderingEmSize="13.333333333333334" 
      DeviceFontName="{x:Null}" 
      AdvanceWidths="9.62666666666667 7.41333333333333 2.96 2.96 7.41333333333333 3.70666666666667 12.5866666666667 7.41333333333333 4.44 2.96 7.41333333333333" 
      BidiLevel="0">
      <GlyphRun.GlyphTypeface>
        <GlyphTypeface FontUri="C:\WINDOWS\Fonts\TIMES.TTF" />
      </GlyphRun.GlyphTypeface>
    </GlyphRun>
  </GlyphRunDrawing.GlyphRun>
</GlyphRunDrawing>

A GlyphRun 是一个低级别对象,用于固定格式的文档演示和打印方案。 将文本绘制到屏幕的一种更简单方法是使用 Label 或使用 TextBlock。 有关GlyphRun的详细信息,请参阅 GlyphRun 对象和 Glyphs 元素的概述

合成绘图

使用 A DrawingGroup 可将多个绘图合并到单个复合绘图中。 通过使用 a DrawingGroup,可以将形状、图像和文本合并到单个 Drawing 对象中。

以下示例使用 DrawingGroup 对两个 GeometryDrawing 对象和一个 ImageDrawing 对象进行组合。 此示例生成以下输出。

具有多个绘图的 DrawingGroup
合成图

//
// Create three drawings.
//
GeometryDrawing ellipseDrawing =
    new GeometryDrawing(
        new SolidColorBrush(Color.FromArgb(102, 181, 243, 20)),
        new Pen(Brushes.Black, 4),
        new EllipseGeometry(new Point(50,50), 50, 50)
    );

ImageDrawing kiwiPictureDrawing =
    new ImageDrawing(
        new BitmapImage(new Uri(@"sampleImages\kiwi.png", UriKind.Relative)),
        new Rect(50,50,100,100));

GeometryDrawing ellipseDrawing2 =
    new GeometryDrawing(
        new SolidColorBrush(Color.FromArgb(102,181,243,20)),
        new Pen(Brushes.Black, 4),
        new EllipseGeometry(new Point(150, 150), 50, 50)
    );

// Create a DrawingGroup to contain the drawings.
DrawingGroup aDrawingGroup = new DrawingGroup();
aDrawingGroup.Children.Add(ellipseDrawing);
aDrawingGroup.Children.Add(kiwiPictureDrawing);
aDrawingGroup.Children.Add(ellipseDrawing2);

<DrawingGroup>

  <GeometryDrawing Brush="#66B5F314">
    <GeometryDrawing.Geometry>
      <EllipseGeometry Center="50,50" RadiusX="50"  RadiusY="50"/>
    </GeometryDrawing.Geometry>
    <GeometryDrawing.Pen>
      <Pen Brush="Black" Thickness="4" />
    </GeometryDrawing.Pen>
  </GeometryDrawing>
  <ImageDrawing ImageSource="sampleImages\kiwi.png" Rect="50,50,100,100"/>
  <GeometryDrawing Brush="#66B5F314">
    <GeometryDrawing.Geometry>
      <EllipseGeometry Center="150,150" RadiusX="50"  RadiusY="50"/>
    </GeometryDrawing.Geometry>
    <GeometryDrawing.Pen>
      <Pen Brush="Black" Thickness="4" />
    </GeometryDrawing.Pen>
  </GeometryDrawing>
</DrawingGroup>

使用 A DrawingGroup ,还可以将不透明度掩码、转换、位图效果和其他操作应用于其内容。 DrawingGroup操作按以下顺序应用:OpacityMaskOpacityBitmapEffectClipGeometryGuidelineSet,然后Transform

下图显示了应用 DrawingGroup 操作的顺序。

DrawingGroup 操作顺序
DrawingGroup 操作的顺序

下表描述了可用于操作 DrawingGroup 对象内容的属性。

资产 DESCRIPTION 图示
OpacityMask 更改DrawingGroup内容选定部分的不透明度。 有关示例,请参阅 “如何:控制绘图的不透明度”。 具有不透明度掩码的图形组
Opacity 统一更改内容的不透明度 DrawingGroup 。 使用此属性使 Drawing 透明或部分透明。 有关示例,请参阅 How to: Apply an Opacity Mask to a Drawing. 具有不同不透明度设置的绘图组
BitmapEffect 将 a BitmapEffect 应用于 DrawingGroup 内容。 有关示例,请参阅 How to: Apply a BitmapEffect to a Drawing. 应用虚化位图效果的绘图组
ClipGeometry DrawingGroup 内容裁剪到由 Geometry 描述的区域。 有关示例,请参阅 如何剪裁绘图 具有定义的剪辑区域的 DrawingGroup
GuidelineSet 按照指定的准则将设备独立像素与设备像素对齐。 此属性有助于确保精细详细的图形在低 DPI 显示器上清晰呈现。 有关示例,请参阅 向绘图应用 GuidelineSet 具有和没有 GuidelineSet 的 DrawingGroup
Transform 转换 DrawingGroup 内容。 有关示例,请参阅 如何:将变换应用于绘图 旋转的绘图组

将绘图显示为图像

为了显示DrawingImage控件,使用DrawingImage作为Image控件的Source,并将DrawingImage对象的DrawingImage.Drawing属性设置为您要展示的绘图。

以下示例使用DrawingImageImage控件来显示GeometryDrawing。 此示例生成以下输出。

两个椭圆的 GeometryDrawing
一幅绘图图像

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SDKSample
{
    public class DrawingImageExample : Page
    {

        public DrawingImageExample()
        {

            //
            // Create the Geometry to draw.
            //
            GeometryGroup ellipses = new GeometryGroup();
            ellipses.Children.Add(
                new EllipseGeometry(new Point(50,50), 45, 20)
                );
            ellipses.Children.Add(
                new EllipseGeometry(new Point(50, 50), 20, 45)
                );

            //
            // Create a GeometryDrawing.
            //
            GeometryDrawing aGeometryDrawing = new GeometryDrawing();
            aGeometryDrawing.Geometry = ellipses;

            // Paint the drawing with a gradient.
            aGeometryDrawing.Brush =
                new LinearGradientBrush(
                    Colors.Blue,
                    Color.FromRgb(204,204,255),
                    new Point(0,0),
                    new Point(1,1));

            // Outline the drawing with a solid color.
            aGeometryDrawing.Pen = new Pen(Brushes.Black, 10);

            //
            // Use a DrawingImage and an Image control
            // to display the drawing.
            //
            DrawingImage geometryImage = new DrawingImage(aGeometryDrawing);

            // Freeze the DrawingImage for performance benefits.
            geometryImage.Freeze();

            Image anImage = new Image();
            anImage.Source = geometryImage;
            anImage.HorizontalAlignment = HorizontalAlignment.Left;

            //
            // Place the image inside a border and
            // add it to the page.
            //
            Border exampleBorder = new Border();
            exampleBorder.Child = anImage;
            exampleBorder.BorderBrush = Brushes.Gray;
            exampleBorder.BorderThickness = new Thickness(1);
            exampleBorder.HorizontalAlignment = HorizontalAlignment.Left;
            exampleBorder.VerticalAlignment = VerticalAlignment.Top;
            exampleBorder.Margin = new Thickness(10);

            this.Margin = new Thickness(20);
            this.Background = Brushes.White;
            this.Content = exampleBorder;
        }
    }
}
<Page 
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:PresentationOptions="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options" 
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  mc:Ignorable="PresentationOptions"
  Background="White" Margin="20">

  <Border BorderBrush="Gray" BorderThickness="1" 
    HorizontalAlignment="Left" VerticalAlignment="Top"
    Margin="10">

    <!-- This image uses a Drawing object for its source. -->
    <Image>
      <Image.Source>
        <DrawingImage PresentationOptions:Freeze="True">
          <DrawingImage.Drawing>
            <GeometryDrawing>
              <GeometryDrawing.Geometry>
                <GeometryGroup>
                  <EllipseGeometry Center="50,50" RadiusX="45" RadiusY="20" />
                  <EllipseGeometry Center="50,50" RadiusX="20" RadiusY="45" />
                </GeometryGroup>
              </GeometryDrawing.Geometry>
              <GeometryDrawing.Brush>
                <LinearGradientBrush>
                  <GradientStop Offset="0.0" Color="Blue" />
                  <GradientStop Offset="1.0" Color="#CCCCFF" />
                </LinearGradientBrush>
              </GeometryDrawing.Brush>
              <GeometryDrawing.Pen>
                <Pen Thickness="10" Brush="Black" />
              </GeometryDrawing.Pen>
            </GeometryDrawing>
          </DrawingImage.Drawing>
        </DrawingImage>
      </Image.Source>
    </Image>
  </Border>

</Page>

使用绘图绘制对象

A DrawingBrush 是一种画笔类型,用于绘制具有绘图对象的区域。 可以使用它通过绘图绘制任何图形对象。 DrawingBrushDrawing属性描述其Drawing。 若要使用 a DrawingBrush呈现,Drawing请使用画笔的属性将其添加到画笔Drawing,并使用画笔绘制图形对象,例如控件或面板。

以下示例使用DrawingBrushGeometryDrawing创建的图案应用于RectangleFill。 此示例生成以下输出。

平铺的 DrawingBrush
与 DrawingBrush 一起使用的 GeometryDrawing

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SDKSample
{
    public class DrawingBrushExample : Page
    {

        public DrawingBrushExample()
        {

            //
            // Create the Geometry to draw.
            //
            GeometryGroup ellipses = new GeometryGroup();
            ellipses.Children.Add(
                new EllipseGeometry(new Point(50,50), 45, 20)
                );
            ellipses.Children.Add(
                new EllipseGeometry(new Point(50, 50), 20, 45)
                );

            //
            // Create a GeometryDrawing.
            //
            GeometryDrawing aGeometryDrawing = new GeometryDrawing();
            aGeometryDrawing.Geometry = ellipses;

            // Paint the drawing with a gradient.
            aGeometryDrawing.Brush =
                new LinearGradientBrush(
                    Colors.Blue,
                    Color.FromRgb(204,204,255),
                    new Point(0,0),
                    new Point(1,1));

            // Outline the drawing with a solid color.
            aGeometryDrawing.Pen = new Pen(Brushes.Black, 10);

            DrawingBrush patternBrush = new DrawingBrush(aGeometryDrawing);
            patternBrush.Viewport = new Rect(0, 0, 0.25, 0.25);
            patternBrush.TileMode = TileMode.Tile;
            patternBrush.Freeze();

            //
            // Create an object to paint.
            //
            Rectangle paintedRectangle = new Rectangle();
            paintedRectangle.Width = 100;
            paintedRectangle.Height = 100;
            paintedRectangle.Fill = patternBrush;

            //
            // Place the image inside a border and
            // add it to the page.
            //
            Border exampleBorder = new Border();
            exampleBorder.Child = paintedRectangle;
            exampleBorder.BorderBrush = Brushes.Gray;
            exampleBorder.BorderThickness = new Thickness(1);
            exampleBorder.HorizontalAlignment = HorizontalAlignment.Left;
            exampleBorder.VerticalAlignment = VerticalAlignment.Top;
            exampleBorder.Margin = new Thickness(10);

            this.Margin = new Thickness(20);
            this.Background = Brushes.White;
            this.Content = exampleBorder;
        }
    }
}
<Page 
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:PresentationOptions="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options" 
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  mc:Ignorable="PresentationOptions"
  Margin="20" Background="White">

  <Border BorderBrush="Gray" BorderThickness="1" 
    HorizontalAlignment="Left" VerticalAlignment="Top"
    Margin="10">
    <Rectangle Width="100" Height="100">
      <Rectangle.Fill>
        <DrawingBrush PresentationOptions:Freeze="True"
                      Viewport="0,0,0.25,0.25" TileMode="Tile">
          <DrawingBrush.Drawing>
            <GeometryDrawing>
              <GeometryDrawing.Geometry>
                <GeometryGroup>
                  <EllipseGeometry Center="50,50" RadiusX="45" RadiusY="20" />
                  <EllipseGeometry Center="50,50" RadiusX="20" RadiusY="45" />
                </GeometryGroup>
              </GeometryDrawing.Geometry>
              <GeometryDrawing.Brush>
                <LinearGradientBrush>
                  <GradientStop Offset="0.0" Color="Blue" />
                  <GradientStop Offset="1.0" Color="#CCCCFF" />
                </LinearGradientBrush>
              </GeometryDrawing.Brush>
              <GeometryDrawing.Pen>
                <Pen Thickness="10" Brush="Black" />
              </GeometryDrawing.Pen>
            </GeometryDrawing>
          </DrawingBrush.Drawing>
        </DrawingBrush>
      </Rectangle.Fill>

    </Rectangle>
  </Border>


</Page>

DrawingBrush 类提供了各种用于拉伸和平铺其内容的选项。 有关详细信息 DrawingBrush,请参阅 “使用图像、绘图和视觉对象绘制” 概述。

使用视觉元素呈现绘图

A DrawingVisual 是一种设计用于呈现绘图的视觉对象。 直接在视觉层工作是希望构建高度自定义图形环境的开发人员的选项,此概述中未介绍。 有关详细信息,请参阅 “使用 DrawingVisual 对象 ”概述。

DrawingContext 对象

DrawingContext 类使你能够将视觉内容填充到 VisualDrawing 中。 许多此类较低级别的图形对象都使用 a DrawingContext ,因为它非常有效地描述了图形内容。

DrawingContext虽然绘图看起来与System.Drawing.Graphics类型的绘图方法相似,但实际上它们非常不同。 DrawingContext 与保留模式图形系统一起使用,而该 System.Drawing.Graphics 类型与即时模式图形系统一起使用。 使用 DrawingContext 对象的绘图命令时,实际上会存储一组渲染指令(尽管确切的存储机制取决于提供DrawingContext的对象类型),这些指令将由图形系统在稍后使用;你并不会实时将内容绘制到屏幕上。 有关 Windows Presentation Foundation (WPF) 图形系统工作原理的详细信息,请参阅 WPF 图形呈现概述

你从不直接实例化 DrawingContext;但是,可以从某些方法(如 DrawingGroup.OpenDrawingVisual.RenderOpen)获取绘图上下文。

枚举视觉对象的内容

除了其他用途之外,Drawing 对象还提供一个对象模型来枚举 Visual的内容。

以下示例使用 GetDrawing 方法检索 DrawingGroupVisual 值并枚举它。

public void RetrieveDrawing(Visual v)
{
    DrawingGroup drawingGroup = VisualTreeHelper.GetDrawing(v);
    EnumDrawingGroup(drawingGroup);
}

// Enumerate the drawings in the DrawingGroup.
public void EnumDrawingGroup(DrawingGroup drawingGroup)
{
    DrawingCollection dc = drawingGroup.Children;

    // Enumerate the drawings in the DrawingCollection.
    foreach (Drawing drawing in dc)
    {
        // If the drawing is a DrawingGroup, call the function recursively.
        if (drawing is DrawingGroup group)
        {
            EnumDrawingGroup(group);
        }
        else if (drawing is GeometryDrawing)
        {
            // Perform action based on drawing type.
        }
        else if (drawing is ImageDrawing)
        {
            // Perform action based on drawing type.
        }
        else if (drawing is GlyphRunDrawing)
        {
            // Perform action based on drawing type.
        }
        else if (drawing is VideoDrawing)
        {
            // Perform action based on drawing type.
        }
    }
}

另请参阅