# 绘制图形Draw shapes

The Shape classes are Line, Ellipse, Rectangle, Polygon, Polyline, and Path. Path 非常有趣，因为它可以定义任意几何图形，同时还会在此处介绍 Geometry 类，因为这是定义部分 Path 的一个方法。Path is interesting because it can define an arbitrary geometry, and the Geometry class is involved here because that's one way to define the parts of a Path.

## 形状的 Fill 和 StrokeFill and Stroke for shapes

Shape 还可以有一个 Stroke（在形状的外围绘制的线条）。A Shape can also have a Stroke, which is a line that is drawn around the shape's perimeter. Stroke 还需要一个用于定义其外观的 Brush，而且其 StrokeThickness 应当具有非零值。A Stroke also requires a Brush that defines its appearance, and should have a non-zero value for StrokeThickness. StrokeThickness 是一个属性，用来定义形状边缘的外围粗细。StrokeThickness is a property that defines the perimeter's thickness around the shape edge. 如果你没有为 Stroke 指定 Brush 值，或者如果你将 StrokeThickness 设置为 0，则将不绘制形状周围的边界。If you don't specify a Brush value for Stroke, or if you set StrokeThickness to 0, then the border around the shape is not drawn.

## EllipseEllipse

Ellipse 是具有弯曲外围的形状。An Ellipse is a shape with a curved perimeter. 若要创建基本的 Ellipse，请为 Fill 指定 WidthHeightBrushTo create a basic Ellipse, specify a Width, Height, and a Brush for the Fill.

``````<Ellipse Fill="SteelBlue" Height="200" Width="200" />
``````
``````var ellipse1 = new Ellipse();
ellipse1.Fill = new SolidColorBrush(Windows.UI.Colors.SteelBlue);
ellipse1.Width = 200;
ellipse1.Height = 200;

// When you create a XAML element in code, you have to add
// it to the XAML visual tree. This example assumes you have
// a panel named 'layoutRoot' in your XAML file, like this:
// <Grid x:Name="layoutRoot>
``````

6 个 Ellipse 元素为一个组，它们属于 ProgressRing 控件的控件模板，并且 2 个同心 Ellipse 元素属于 RadioButtonA set of 6 Ellipse elements are part of the control template for the ProgressRing control, and 2 concentric Ellipse elements are part of a RadioButton.

## RectangleRectangle

Rectangle 形状有四个边而且相对的两个边相等。A Rectangle is a four-sided shape with its opposite sides being equal. 若要创建基本的 Rectangle，请指定 WidthHeightFillTo create a basic Rectangle, specify a Width, a Height, and a Fill.

``````<Rectangle Fill="Blue"
Width="200"
Height="100"
Stroke="Black"
StrokeThickness="3"
``````
``````var rectangle1 = new Rectangle();
rectangle1.Fill = new SolidColorBrush(Windows.UI.Colors.Blue);
rectangle1.Width = 200;
rectangle1.Height = 100;
rectangle1.Stroke = new SolidColorBrush(Windows.UI.Colors.Black);
rectangle1.StrokeThickness = 3;

// When you create a XAML element in code, you have to add
// it to the XAML visual tree. This example assumes you have
// a panel named 'layoutRoot' in your XAML file, like this:
// <Grid x:Name="layoutRoot>
``````

## PolygonPolygon

Polygon 是通过任意数量的点来定义边的形状。A Polygon is a shape with a boundary defined by an arbitrary number of points. 边通过用直线将点一个一个连接起来（最后一个点与第一个点相连）而创建。The boundary is created by connecting a line from one point to the next, with the last point connected to the first point. Points 属性定义组成边的点集。The Points property defines the collection of points that make up the boundary. 在 XAML 中，使用逗号分隔的列表定义点。In XAML, you define the points with a comma-separated list. 在代码隐藏文件中，使用 PointCollection 定义各个点，并将每个点作为一个 Point 值添加到集合中。In code-behind you use a PointCollection to define the points and you add each individual point as a Point value to the collection.

``````<Polygon Fill="LightBlue"
Points="10,200,60,140,130,140,180,200" />
``````
``````var polygon1 = new Polygon();
polygon1.Fill = new SolidColorBrush(Windows.UI.Colors.LightBlue);

var points = new PointCollection();
polygon1.Points = points;

// When you create a XAML element in code, you have to add
// it to the XAML visual tree. This example assumes you have
// a panel named 'layoutRoot' in your XAML file, like this:
// <Grid x:Name="layoutRoot>
``````

## LineLine

Line 只是一条在坐标空间中的两个点之间绘制的直线。A Line is simply a line drawn between two points in coordinate space. Line 忽略为 Fill 提供的任何值，因为它没有内部空间。A Line ignores any value provided for Fill, because it has no interior space. 对于 Line，请确保为 StrokeStrokeThickness 属性指定值，否则 Line 将不呈现。For a Line, make sure to specify values for the Stroke and StrokeThickness properties, because otherwise the Line won't render.

``````<Line Stroke="Red" X2="400"/>
``````
``````var line1 = new Line();
line1.Stroke = new SolidColorBrush(Windows.UI.Colors.Red);
line1.X2 = 400;

// When you create a XAML element in code, you have to add
// it to the XAML visual tree. This example assumes you have
// a panel named 'layoutRoot' in your XAML file, like this:
// <Grid x:Name="layoutRoot>
``````

## Polyline Polyline

PolylinePolygon 类似，该形状的边也是通过一组点来进行定义，只不过 Polyline 的最后一个点不与第一个点相连。A Polyline is similar to a Polygon in that the boundary of the shape is defined by a set of points, except the last point in a Polyline is not connected to the first point.

``````<Polyline Stroke="Black"
StrokeThickness="4"
Points="10,200,60,140,130,140,180,200" />
``````
``````var polyline1 = new Polyline();
polyline1.Stroke = new SolidColorBrush(Windows.UI.Colors.Black);
polyline1.StrokeThickness = 4;

var points = new PointCollection();
polyline1.Points = points;

// When you create a XAML element in code, you have to add
// it to the XAML visual tree. This example assumes you have
// a panel named 'layoutRoot' in your XAML file, like this:
// <Grid x:Name="layoutRoot>
``````

## 路径Path

Path 是最通用的 Shape，因为使用它可以定义任意几何图形。A Path is the most versatile Shape because you can use it to define an arbitrary geometry. 但是这种通用性非常复杂。But with this versatility comes complexity. 让我们来看看如何在 XAML 中创建一个基本的 PathLet's now look at how to create a basic Path in XAML.

• 你可以在 XAML 中为 Data 定义字符串值。You can set a string value for Data in XAML. 在这种形状中，Path.Data 值对于图形采用序列化格式。In this form, the Path.Data value is consuming a serialization format for graphics. 在首次设置了该值后，你通常无需以字符串对该值进行文本编辑。You typically don't text-edit this value in string form after it is first established. 而是应当使用能够在图面上的设计或绘制标记中工作的设计工具。Instead, you use design tools that enable you to work in a design or drawing metaphor on a surface. 然后，可以保存或导出输出内容，系统会为你提供一个包含 Path.Data 信息的 XAML 文件或 XAML 字符串片段。Then you save or export the output, and this gives you a XAML file or XAML string fragment with Path.Data information.
• 可以将 Data 属性设置为单个 Geometry 对象。You can set the Data property to a single Geometry object. 这可以通过在代码或在 XAML 中来完成。This can be done in code or in XAML. 这个 Geometry 通常是充当容器的 GeometryGroup，该容器可以将多个几何图形定义组合到单个对象中以形成对象模型。That single Geometry is typically a GeometryGroup, which acts as a container that can composite multiple geometry definitions into a single object for purposes of the object model. 这样做最常见的理由是，你希望使用一个或多个可以定义为 PathFigureSegments 值（例如 BezierSegment）的曲线和复杂形状。The most common reason for doing this is because you want to use one or more of the curves and complex shapes that can be defined as Segments values for a PathFigure, for example BezierSegment.

Data 从 move 命令（由“M”指示）开始，该命令为此路径指定起点的绝对值。This Data begins with the move command, indicated by "M", which establishes an absolute start point for the path.

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

``````<Path Stroke="Black" StrokeThickness="1" Fill="#CCCCFF">
<Path.Data>
<GeometryGroup>
<RectangleGeometry Rect="50,5 100,10" />
<RectangleGeometry Rect="5,5 95,180" />
<RectangleGeometry Rect="50,175 100,10" />
<PathGeometry>
<PathGeometry.Figures>
<PathFigureCollection>
<PathFigure IsClosed="true" StartPoint="50,50">
<PathFigure.Segments>
<PathSegmentCollection>
<BezierSegment Point1="75,300" Point2="125,100" Point3="150,50"/>
<BezierSegment Point1="125,300" Point2="75,100"  Point3="50,50"/>
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
</PathFigureCollection>
</PathGeometry.Figures>
</PathGeometry>
</GeometryGroup>
</Path.Data>
</Path>
``````
``````var path1 = new Windows.UI.Xaml.Shapes.Path();
path1.Fill = new SolidColorBrush(Windows.UI.Color.FromArgb(255, 204, 204, 255));
path1.Stroke = new SolidColorBrush(Windows.UI.Colors.Black);
path1.StrokeThickness = 1;

var geometryGroup1 = new GeometryGroup();
var rectangleGeometry1 = new RectangleGeometry();
rectangleGeometry1.Rect = new Rect(50, 5, 100, 10);
var rectangleGeometry2 = new RectangleGeometry();
rectangleGeometry2.Rect = new Rect(5, 5, 95, 180);

var ellipseGeometry1 = new EllipseGeometry();
ellipseGeometry1.Center = new Point(100, 100);

var pathGeometry1 = new PathGeometry();
var pathFigureCollection1 = new PathFigureCollection();
var pathFigure1 = new PathFigure();
pathFigure1.IsClosed = true;
pathFigure1.StartPoint = new Windows.Foundation.Point(50, 50);
pathGeometry1.Figures = pathFigureCollection1;

var pathSegmentCollection1 = new PathSegmentCollection();
var pathSegment1 = new BezierSegment();
pathSegment1.Point1 = new Point(75, 300);
pathSegment1.Point2 = new Point(125, 100);
pathSegment1.Point3 = new Point(150, 50);

var pathSegment2 = new BezierSegment();
pathSegment2.Point1 = new Point(125, 300);
pathSegment2.Point2 = new Point(75, 100);
pathSegment2.Point3 = new Point(50, 50);
pathFigure1.Segments = pathSegmentCollection1;