Обзор фигур и базовых средств рисования в приложении WPF
В этом разделе содержится обзор рисования с помощью объектов Shape. Объект Shape является типом объекта UIElement, который позволяет нарисовать фигуру на экране. Так как объекты Shape являются элементами пользовательского интерфейса, они могут использоваться внутри элементов Panel и большинства элементов управления.
Windows Presentation Foundation (WPF) предоставляет несколько уровней доступа к изображениям и службам визуализации. На верхнем слое объекты Shape просты в использовании и предоставляют множество полезных возможностей, таких как разметка и участие в системе событий Windows Presentation Foundation (WPF).
В этом разделе содержатся следующие подразделы.
- Объекты фигур
- Использование путей и геометрических фигур
- Рисование фигур
- Растягиваемые фигуры
- Преобразование фигур
- Связанные разделы
Объекты фигур
WPF предоставляет ряд готовых к использованию объектов Shape. Все объекты фигур наследуются из класса Shape. Доступны объекты фигур Ellipse, Line, Path, Polygon, Polyline и Rectangle. Объекты Shape используют следующие общие свойства.
Stroke: описывает способ рисования контура фигуры.
StrokeThickness: описывает толщину контура фигуры.
Fill: описывает способ закрашивания внутренней части фигуры.
Свойства данных, определяющие координаты и вершины, измеряемые в аппаратно независимых точках.
Поскольку объекты фигур являются производными класса UIElement, они могут использоваться внутри панелей и большинства элементов управления. Панель Canvas особенно подходит для создания сложных рисунков, поскольку она поддерживает абсолютное позиционирование дочерних объектов.
Класс Line позволяет нарисовать линию между двумя точками. В следующем примере показано несколько способов указания координат линии и свойств штриха.
<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>
' Add a Line Element
Dim myLine As New Line()
myLine.Stroke = Brushes.LightSteelBlue
myLine.X1 = 1
myLine.X2 = 50
myLine.Y1 = 1
myLine.Y2 = 50
myLine.HorizontalAlignment = HorizontalAlignment.Left
myLine.VerticalAlignment = VerticalAlignment.Center
myLine.StrokeThickness = 2
myGrid.Children.Add(myLine)
// Add a Line Element
myLine = new Line();
myLine.Stroke = System.Windows.Media.Brushes.LightSteelBlue;
myLine.X1 = 1;
myLine.X2 = 50;
myLine.Y1 = 1;
myLine.Y2 = 50;
myLine.HorizontalAlignment = HorizontalAlignment.Left;
myLine.VerticalAlignment = VerticalAlignment.Center;
myLine.StrokeThickness = 2;
myGrid.Children.Add(myLine);
// Add a Line Element
myLine = gcnew Line();
myLine->Stroke = Brushes::LightSteelBlue;
myLine->X1 = 1;
myLine->X2 = 50;
myLine->Y1 = 1;
myLine->Y2 = 50;
myLine->HorizontalAlignment = HorizontalAlignment::Left;
myLine->VerticalAlignment = VerticalAlignment::Center;
myLine->StrokeThickness = 2;
myGrid->Children->Add(myLine);
На следующем рисунке показан отображаемый класс Line.
Несмотря на то, что класс Line предоставляет свойство Fill, его установка не влияет на объект, так как Line не имеет внутренней области.
Другой общей фигурой является Ellipse. Создайте объект Ellipse, определив свойства Width и Height фигуры. Чтобы нарисовать круг, определите объект Ellipse значения которого Width и Height равны.
<Ellipse
Fill="Yellow"
Height="100"
Width="200"
StrokeThickness="2"
Stroke="Black"/>
Imports Microsoft.VisualBasic
Imports System
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Media
Imports System.Windows.Shapes
Namespace SDKSample
Partial Public Class SetBackgroundColorOfShapeExample
Inherits Page
Public Sub New()
' Create a StackPanel to contain the shape.
Dim myStackPanel As New StackPanel()
' Create a red Ellipse.
Dim myEllipse As New Ellipse()
' Create a SolidColorBrush with a red color to fill the
' Ellipse with.
Dim mySolidColorBrush As New SolidColorBrush()
' Describes the brush's color using RGB values.
' Each value has a range of 0-255.
mySolidColorBrush.Color = Color.FromArgb(255, 255, 255, 0)
myEllipse.Fill = mySolidColorBrush
myEllipse.StrokeThickness = 2
myEllipse.Stroke = Brushes.Black
' Set the width and height of the Ellipse.
myEllipse.Width = 200
myEllipse.Height = 100
' Add the Ellipse to the StackPanel.
myStackPanel.Children.Add(myEllipse)
Me.Content = myStackPanel
End Sub
End Class
End Namespace
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
namespace SDKSample
{
public partial class SetBackgroundColorOfShapeExample : Page
{
public SetBackgroundColorOfShapeExample()
{
// Create a StackPanel to contain the shape.
StackPanel myStackPanel = new StackPanel();
// Create a red Ellipse.
Ellipse myEllipse = new Ellipse();
// Create a SolidColorBrush with a red color to fill the
// Ellipse with.
SolidColorBrush mySolidColorBrush = new SolidColorBrush();
// Describes the brush's color using RGB values.
// Each value has a range of 0-255.
mySolidColorBrush.Color = Color.FromArgb(255, 255, 255, 0);
myEllipse.Fill = mySolidColorBrush;
myEllipse.StrokeThickness = 2;
myEllipse.Stroke = Brushes.Black;
// Set the width and height of the Ellipse.
myEllipse.Width = 200;
myEllipse.Height = 100;
// Add the Ellipse to the StackPanel.
myStackPanel.Children.Add(myEllipse);
this.Content = myStackPanel;
}
}
}
На следующем рисунке показан пример отображаемого объекта Ellipse.
Использование путей и геометрических фигур
Класс Path позволяет рисовать кривые линии и сложные фигуры. Эти кривые линии и фигуры описываются с помощью объектов Geometry. Чтобы использовать объект Path, создайте объект Geometry и используйте его, чтобы задать свойство Data объекта Path.
Имеется выбор из различных объектов Geometry. Классы LineGeometry, RectangleGeometry и EllipseGeometry описывают относительно простые фигуры. Для создания более сложных фигур или кривых линий используйте класс PathGeometry.
PathGeometry и PathSegments
Объекты PathGeometry составлены из одного или нескольких объектов PathFigure; каждый объект PathFigure представляет отдельную "фигуру" или форму. Каждый объект PathFigure состоит из одного или нескольких объектов PathSegment, каждый из которых представляет переходную часть фигуры или формы. Типы сегментов включают следующие объекты: LineSegment, BezierSegment и ArcSegment.
В следующем примере объект Path используется для рисования кривой Безье второго порядка.
<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. В следующем примере сокращенный синтаксис используется для рисования сложной фигуры.
<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). Этот сегмент определен командой C в строке атрибута Data. Опять же заглавная буква C указывает абсолютный путь; строчная буква c указывала бы относительный путь.
Второй сегмент начинается с абсолютной команды горизонтали lineto, обозначенной буквой H, которая определяет, что линия проведена от предшествующей конечной точки подпути (400,175) к новой конечной точке (280,175). Поскольку это команда горизонтали lineto, указанное значение является координатой x.
Полный синтаксис пути см. в ссылке в свойства Data и в разделе Практическое руководство. Создание фигуры с помощью PathGeometry.
Рисование фигур
Объекты Brush используются для рисования свойств Stroke и Fill фигуры. В следующем примере задается штриховка и заливка объекта Ellipse. Обратите внимание, что допустимые входные данные свойств кисти могут быть либо ключевым словом, либо шестнадцатеричным значением цвета. Для дополнительных сведений о доступных ключевых словах цветов см. свойства класса Colors в пространстве имен System.Windows.Media.
<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>
На следующем рисунке показана отображенная фигура.
Можно также заштриховать фигуру или заполнить градиентами, изображениями, узорами и т.д. Дополнительные сведения см. в разделе Общие сведения о закраске сплошным цветом и градиентом.
Растягиваемые фигуры
Все классы Line, Path, Polygon, Polyline и Rectangle имеют свойство Stretch. Это свойство определяет, как содержимое объекта Shape (фигура, которая будет нарисована) должно быть растянуто для заполнения пространства макета объекта Shape. Пространство макета объекта Shape — это количество пространства, которое система выделила для размещения объекта Shape или явным заданием параметра Width и Height, или с учетом параметров HorizontalAlignment и VerticalAlignment. Дополнительные сведения о макете в Windows Presentation Foundation содержатся в обзоре Система макета.
Свойство растягивания принимает одно из следующих значений:
Fill: содержимое объекта Shape растягивается для заполнения пространства макета. Коэффициент пропорциональности не сохраняется.
Uniform: содержимое объекта Shape растягивается, насколько это возможно для заполнения пространства макета с сохранением исходного коэффициента пропорциональности.
UniformToFill: содержимое объекта Shape растягивается до полного заполнения пространства макета с сохранением исходного коэффициента пропорциональности.
Обратите внимание, что когда содержимое объекта Shape растянуто, контур объекта Shape рисуется после растягивания.
В следующем примере используется объект Polygon для рисования очень небольшого треугольника с вершинами (0,0), (0,1) и (1,1). Свойства Width и Height объекта Polygon имеют значение 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. Значение свойства Angle 45 поворачивает элемент на 45 градусов по часовой стрелке; угол 90 поворачивает элемент на 90 градусов по часовой стрелке; и т. д. Установите свойства CenterX и CenterY, если нужно управлять точкой вращения элемента. Эти значения свойств выражены в координатном пространстве элемента, к которому применяется преобразование. Свойства CenterX и CenterY по умолчанию имеют нулевые значения. Наконец, примените объект RotateTransform к элементу. Если не требуется воздействия преобразования на макет, установите свойство RenderTransform фигуры.
В следующем примере для поворота фигуры на 45 градусов относительно левого верхнего угла (0,0) используется объект RotateTransform.
<!-- 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).
<!-- 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>
Ниже показаны результаты применения двух преобразований.
В предыдущих примерах одно преобразование было применено к каждому объекту фигуры. Чтобы применить несколько преобразований к фигуре (или любому другому элементу пользовательского интерфейса), используйте объект TransformGroup.
См. также
Основные понятия
Оптимизация производительности: двумерная графика и обработка изображений
Общие сведения о закраске сплошным цветом и градиентом
Общие сведения о классе Geometry