本主题概述如何使用 Shape 对象绘图。 Shape 是一种允许您在屏幕中绘制形状的 UIElement 类型。 由于它们是 UI 元素,因此 Shape 对象可以在 Panel 元素和大多数控件中使用。

Windows Presentation Foundation (WPF) 提供了对图形和呈现服务的若干层访问。 在顶层,Shape 对象很容易使用,并且提供了许多有用功能,例如布局和参与 Windows Presentation Foundation (WPF) 事件系统。

本主题包括下列各节。

  • 形状对象
  • 使用 Path 和 Geometry
  • 绘制形状
  • 可拉伸形状
  • 变换形状
  • 相关主题

形状对象

WPF 提供了许多易于使用的 Shape 对象。 所有形状对象都是从 Shape 类继承的。 可用的 Shape 对象包括 EllipseLinePathPolygonPolyline 和 RectangleShape 对象共享以下通用属性。

  • Stroke:说明如何绘制形状的轮廓。

  • StrokeThickness:说明形状轮廓的粗细。

  • Fill:说明如何绘制形状的内部。

  • 用于指定坐标和顶点的数据属性,以与设备无关的像素来度量。

由于形状对象派生于 UIElement,因此可以在面板和大多数控件中使用。 Canvas 面板是用于创建复杂绘图的特别理想的选择,因为它支持对其子对象的绝对定位。

使用 Line 类可以在两个点之间绘制一条直线。 下面的示例演示了几种指定线条坐标和描边属性的方法。

XAML复制

 
<Canvas Height="300" Width="300">

  <!-- Draws a diagonal line from (10,10) to (50,50). -->
<Line
X1="10" Y1="10"
X2="50" Y2="50"
Stroke="Black"
StrokeThickness="4" /> <!-- Draws a diagonal line from (10,10) to (50,50)
and moves it 100 pixels to the right. -->
<Line
X1="10" Y1="10"
X2="50" Y2="50"
StrokeThickness="4"
Canvas.Left="100">
<Line.Stroke>
<RadialGradientBrush GradientOrigin="0.5,0.5" Center="0.5,0.5" RadiusX="0.5" RadiusY="0.5">
<RadialGradientBrush.GradientStops>
<GradientStop Color="Red" Offset="0" />
<GradientStop Color="Blue" Offset="0.25" />
</RadialGradientBrush.GradientStops>
</RadialGradientBrush>
</Line.Stroke>
</Line> <!-- Draws a horizontal line from (10,60) to (150,60). -->
<Line
X1="10" Y1="60"
X2="150" Y2="60"
Stroke="Black"
StrokeThickness="4"/> </Canvas>

下图显示了所呈现的 Line

虽然 Line 类提供了 Fill 属性,但设置该属性无效,因为 Line 没有区域。

另一个常用形状是 Ellipse。 通过定义形状的 Width 和 Height 属性来创建 Ellipse。 若要绘制一个圆,请指定一个其 Width 和 Height 值相等的 Ellipse

XAML复制

 
        <Ellipse
Fill="Yellow"
Height="100"
Width="200"
StrokeThickness="2"
Stroke="Black"/>

下图显示了一个已呈现 Ellipse 的示例。

使用 Path 和 Geometry

使用 Path 类可以绘制曲线和复杂形状。 这些曲线和形状使用 Geometry 对象来说明 若要使用 Path,请创建一个 Geometry 并使用它来设置 Path 对象的 Data 属性。

可以从各种 Geometry 对象中进行选择。 LineGeometryRectangleGeometry 和 EllipseGeometry 类说明了相对简单的形状。 若要创建更复杂的形状或创建曲线,请使用 PathGeometry

PathGeometry 和 PathSegment

PathGeometry 对象由一个或多个 PathFigure 对象组成;每个 PathFigure 代表一个不同的“图形”或形状。 每个 PathFigure 自身又由一个或多个 PathSegment 对象组成,每个对象均代表图形或形状的已连接部分。 Segment 类型包括 LineSegmentBezierSegment 和 ArcSegment

在下面的示例中,使用一个 Path 来绘制二次方贝塞尔曲线。

XAML复制

 
<Path Stroke="Black" StrokeThickness="1">
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigureCollection>
<PathFigure StartPoint="10,100">
<PathFigure.Segments>
<PathSegmentCollection>
<QuadraticBezierSegment Point1="200,200" Point2="300,100" />
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
</PathFigureCollection>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>

下图显示了所呈现的形状。

有关 PathGeometry 和其他 Geometry 类的更多信息,请参见 Geometry 概述

XAML 缩写语法

在Extensible Application Markup Language (XAML) 中,还可以使用一种特殊的缩写语法来说明 Path。 在下面的示例中,使用缩写语法来绘制一个复杂形状。

XAML复制

 
<Path Stroke="DarkGoldenRod" StrokeThickness="3"
Data="M 100,200 C 100,25 400,350 400,175 H 280" />

下面的图像显示了一个已呈现的 Path

Data 特性字符串以“moveto”命令开头(由 M 指示),它为 Canvas 的坐标系统中的路径建立一个起点。 Path数据参数区分大小写。 大写的 M 指示新的当前点的绝对位置。 小写 m 则指示相对坐标。 第一段是一个三次方贝塞尔曲线,该曲线从 (100,200) 开始,在 (400,175) 结束,使用 (100,25) 和 (400,350) 这两个控制点绘制。 此段由 Data 特性字符串中的 C 命令指示。 同样,大写的 C 指示绝对路径;小写的 c 则指示相对路径。

第二段以绝对水平“lineto”命令 H 开头,它指定绘制一条从前面的子路径的终结点 (400,175) 到新终结点 (280,175) 的直线。 由于它是一个水平“lineto”命令,因此指定的值是 x 坐标。

有关完整的路径语法,请参见 Data 参考内容和如何:使用 PathGeometry 创建形状

绘制形状

Brush 对象用于绘制形状的 Stroke 和 Fill。 在下面的示例中,指定了 Ellipse 的描边和填充。 请注意,画笔属性的有效输入可以是关键字或十六进制颜色值。 有关可用的颜色关键字的更多信息,请参见 System.Windows.Media 命名空间中 Colors 类的属性。

复制

 
<Canvas Background="LightGray">
<Ellipse
Canvas.Top="50"
Canvas.Left="50"
Fill="#FFFFFF00"
Height="75"
Width="75"
StrokeThickness="5"
Stroke="#FF0000FF"/>
</Canvas>

下图显示了所呈现的 Ellipse

您也可以使用属性元素语法显式创建一个 SolidColorBrush 对象,以使用纯色绘制形状。

复制

 
<!-- This polygon shape uses pre-defined color values for its Stroke and
Fill properties.
The SolidColorBrush's Opacity property affects the fill color in
this case by making it slightly transparent (opacity of 0.4) so
that it blends with any underlying color. --> <Polygon
Points="300,200 400,125 400,275 300,200"
Stroke="Purple"
StrokeThickness="2">
<Polygon.Fill>
<SolidColorBrush Color="Blue" Opacity="0.4"/>
</Polygon.Fill>
</Polygon>

下图显示呈现的形状。

还可以绘制形状的带有渐变、图像、图案等效果的描边或填充。 有关更多信息,请参见 使用纯色和渐变进行绘制概述

可拉伸形状

LinePathPolygonPolyline 和 Rectangle 类都有一个 Stretch 属性。 该属性确定如何拉伸 Shape 对象的内容(要绘制的形状)以填充 Shape 对象的布局空间。 Shape 对象的布局空间是布局系统分配给 Shape(根据显式的 Width 和 Height 设置,或其 HorizontalAlignment 和 VerticalAlignment 设置)的空间量。 有关 Windows Presentation Foundation 中的布局的更多信息,请参见布局系统概述。

Stretch 属性使用以下值之一:

  • None:不拉伸 Shape 对象的内容。

  • Fill:拉伸 Shape 对象的内容以填充其布局空间。 不保留长宽比。

  • Uniform:尽可能地拉伸 Shape 对象的内容以填充其布局空间,同时保留其原始长宽比。

  • UniformToFill:完全拉伸 Shape 对象的内容以填充其布局空间,同时保留其原始长宽比。

请注意,在拉伸 Shape 对象的内容时,会在拉伸之后绘制 Shape 对象的轮廓。

在下面的示例中,使用一个 Polygon 从 (0,0) 到 (0,1),再到 (1,1) 绘制一个非常小的三角形。 Polygon 对象的 Width 和 Height 设置为 100,其拉伸属性设置为 Fill。 结果是,将拉伸 Polygon 对象的内容(三角形)以填充更大的空间。

复制

 
...
<Polygon
Points="0,0 0,1 1,1"
Fill="Blue"
Width="100"
Height="100"
Stretch="Fill"
Stroke="Black"
StrokeThickness="2" />
... ...
PointCollection myPointCollection = new PointCollection();
myPointCollection.Add(new Point(0,0));
myPointCollection.Add(new Point(0,1));
myPointCollection.Add(new Point(1,1)); Polygon myPolygon = new Polygon();
myPolygon.Points = myPointCollection;
myPolygon.Fill = Brushes.Blue;
myPolygon.Width = 100;
myPolygon.Height = 100;
myPolygon.Stretch = Stretch.Fill;
myPolygon.Stroke = Brushes.Black;
myPolygon.StrokeThickness = 2;
...

变换形状

Transform 类提供了在二维平面中变换形状的方法。 不同类型的变换包括旋转 (RotateTransform)、缩放 (ScaleTransform)、斜切 (SkewTransform) 和转换 (TranslateTransform)。

经常应用于形状的变换操作是旋转。 若要旋转形状,请创建一个 RotateTransform 并指定其 Angle。 45 度的 Angle 将元素沿顺时针方向旋转 45 度;90 度将元素沿顺时针方向旋转 90 度;依此类推。 如果您要控制元素的旋转点,请设置 CenterX 和 CenterY 属性。 这些属性值以要变换元素的坐标空间表示。 CenterX 和 CenterY具有默认值零。 最后,将 RotateTransform 应用于该元素。 如果您不希望变形影响到布局,请设置形状的 RenderTransform 属性。

在下面的示例中,使用 RotateTransform 将形状围绕其左上角 (0,0) 旋转 45 度。

XAML复制

 
<!-- Rotates the Polyline 45 degrees about the point (0,0). -->
<Polyline Points="25,25 0,50 25,75 50,50 25,25 25,0"
Stroke="Blue" StrokeThickness="10"
Canvas.Left="75" Canvas.Top="50">
<Polyline.RenderTransform>
<RotateTransform CenterX="0" CenterY="0" Angle="45" />
</Polyline.RenderTransform>
</Polyline>

在下一个示例中,另一个形状将旋转 45 度,但这一次围绕点 (25,50) 进行旋转。

XAML复制

 
<!-- Rotates the Polyline 45 degrees about its center. -->
<Polyline
Points="25,25 0,50 25,75 50,50 25,25 25,0"
Stroke="Blue" StrokeThickness="10"
Canvas.Left="75" Canvas.Top="50"
RenderTransformOrigin="0.5,0.5">
<Polyline.RenderTransform>
<RotateTransform Angle="45" />
</Polyline.RenderTransform>
</Polyline>

下图显示了应用这两种变形的结果。

在上一个示例中,向每个形状对象应用了一次变形。 若要向一个形状(或任何其他 UI 元素)应用多次变形,请使用 TransformGroup

请参见

概念

优化性能:二维图形和图像处理

使用纯色和渐变进行绘制概述

Geometry 概述

演练:开始使用 WPF

动画概述

WPF 中的形状和基本绘图概述的更多相关文章

  1. WPF中获取形状范围

    在没加入到Canvas时,也能获取形状的方法: var polygon = new Polygon(); polygon.Points.Add(new Point(xStart, yStart)); ...

  2. WPF中的导航框架(一)——概述

    有的时候,我们需要一个支持页面跳转的UI,例如文件浏览器,开始向导等.对于这样的界面,简单的可以使用ContentControl + ContentTemplateSelector的方式来实现,但是有 ...

  3. WPF 动画(形状、画刷)

    一:形状 在WPF用户界面中,可以通过形状(Shape)来绘制直线.椭圆.矩形及一些多边形的类.通过这些基本的图像,组合成为复杂的图形. Shape类中,主要的形状有Rectangle(),Ellip ...

  4. WPF中DPI的问题

    先搞清楚一下几个概念: DPI:dots  per  inch ,每英寸的点数.我们常说的鼠标DPI,是指鼠标移动一英寸的距离滑过的点数:打印DPI,每英寸的长度打印的点数:扫描DPI,每英寸扫描了多 ...

  5. WPF中的3D特性和常见的几个类

    原文:WPF中的3D特性和常见的几个类 WPF 3D 常用的几个类及其关系 1.  Visual 类      所有二维可视化元素的基类,为 WPF 中的呈现提供支持,其中包括命中测试.坐标转换和边界 ...

  6. 在WPF中添加3D特性

    原文:在WPF中添加3D特性 35.4  在WPF中添加3D特性 本节介绍WPF中的3D特性,其中包含了开始使用该特性的信息. 提示: WPF中的3D特性在System.Windows.Media.M ...

  7. wpf 中的style

    我们通常说的模板是用来参照的,同样在WPF中,模板是用来作为制作控件的参照. 一.认识模板 1.1WPF菜鸟看模板 前面的记录有提过,控件主要是算法和数据的载体.控件的算法主要体现在可以激发的事件.可 ...

  8. WPF中的动画——(三)时间线(TimeLine)

    WPF中的动画——(三)时间线(TimeLine) 时间线(TimeLine)表示时间段. 它提供的属性可以让控制该时间段的长度.开始时间.重复次数.该时间段内时间进度的快慢等等.在WPF中内置了如下 ...

  9. WPF中图形表示语法详解(Path之Data属性语法)ZZ

    大可山 [MSN:a3news(AT)hotmail.com] http://www.zpxp.com 萝卜鼠在线图形图像处理 ------------------------------------ ...

随机推荐

  1. ArrayList 从源码角度剖析底层原理

    本篇文章已放到 Github github.com/sh-blog 仓库中,里面对我写的所有文章都做了分类,更加方便阅读.同时也会发布一些职位信息,持续更新中,欢迎 Star 对于 ArrayList ...

  2. python 操作word

    pip install python.docx from docx import DocumentDoc = Document() 解释:from 从 docx这个文件中,导入一个叫Document的 ...

  3. python all any函数(相反)

    ''' all() 函数用于判断给定的可迭代参数 iterable 中的所有元素是否都为 TRUE,如果是返回 True,否则返回 False. 元素除了是 0.空.FALSE 外都算 TRUE. 语 ...

  4. Java多线程(下)

    线程同步 当多个线程访问一个对象时,有可能会发生污读,即读取到未及时更新的数据,这个时候就需要线程同步. 线程同步: 即当有一个线程在对内存进行操作时,其他线程都不可以对这个内存地址进行操作,直到该线 ...

  5. 给你的Mac 整个好用的命令行iTerm2 + zsh + oh-my-zsh + powerlevel10k

    给你的Mac 整个好用的命令行iTerm2 + zsh + oh-my-zsh + powerlevel10k 介绍 iTerm2 是一个MacOS 下的终端模拟器,和其他的终端本质上没啥大不同.但相 ...

  6. java 8新特性 并行流

    使用并行流,提高cpu利用率,提高运算速度 /** * java 8并行流 * 底层运用fork join框架 */ @Test public void test(){ Instant start = ...

  7. 第五十三篇 -- MFC美化界面2

    IDC_STATIC 1. 设置字体样式 方法1:在OnInitDialog()函数中使用以下语句 CFont * f; f = new CFont; f->CreateFont(50, // ...

  8. 手把手教你玩转HarmonyOS版地图应用开发

    ​一.导读 7月31日,华为HarmonyOS开发者日将在杭州举行.为了方便更多开发者,高德开放平台地图SDK已在业内率先实现鸿蒙化迁移和重构,全面适配HarmonyOS并面向开发者免费发布.开发者可 ...

  9. 一文彻底弄懂cookie、session、token

    前言 作为一个JAVA开发,之前有好几次出去面试,面试官都问我,JAVAWeb掌握的怎么样,我当时就不知道怎么回答,Web,日常开发中用的是什么?今天我们来说说JAVAWeb最应该掌握的三个内容. 发 ...

  10. JS系统函数

    1. parseInt--转为整型 2. parseFloat--转为浮点型 3. Number--转为数字型 4. isFinite()--检测一个值是否为有限值,如果是返回true,否则就是Inf ...