Тип Polyline позволяет определить коллекцию координат (х, у) (через свойство Points) для рисования последовательности линейных сегментов, не требующих замыкания. Тип Polygon похож, но запрограммирован так, что всегда замыкает контур, соединяя начальную точку с конечной, и заполняет внутреннюю область с помощью указанной кисти. Предположим, что в редакторе Kaxaml создан следующий элемент StackPanel:
Points ="10,10 40,40
10,90 300,50"/>
Points ="40,10 70,80 10,50" />
На рис. 26.2 показан визуализированный вывод в Kaxaml.
Работа с элементом Path
Применяя только типы Rectangle, Ellipse, Polygon, Polyline и Line, нарисовать детализированное двумерное векторное изображение было бы исключительно трудно, т.к. упомянутые примитивы не позволяют легко фиксировать графические данные, подобные кривым, объединениям перекрывающихся данных и т.д. Последний производный от Shape класс, Path, предоставляет возможность определения сложных двумерных графических данных в виде коллекции независимых Data класса Path, где она будет использоваться для визуализации сложного двумерного изображения.
Свойство Data получает объект класса, производного от System.Windows.Media.Geometry, который содержит ключевые члены, кратко описанные в табл. 26.2.
Классы, которые расширяют класс Geometry (табл. 26.3), выглядят очень похожими на свои аналоги, производные от Shape. Например, класс EllipseGeometry имеет члены, подобные членам класса Ellipse. Крупное отличие связано с тем, что производные от Geometry классы не знают, каким образом визуализировать себя напрямую, поскольку они не являются UIElement. Взамен классы, производные от Geometry, представляют всего лишь коллекцию данных о точках, которая указывает объекту Path, как их визуализировать.
На заметку! Класс Path не является единственным классом в инфраструктуре WPF, который способен работать с коллекцией геометрических объектов. Например, классы DoubleAnimationUsingPath, DrawingGroup, GeometryDrawing и даже UIElement могут использовать геометрические объекты для визуализации с применением свойств PathGeometry, ClipGeometry, Geometry и Clip соответственно.
В показанной далее разметке для элемента Path используется несколько типов, производных от Geometry. Обратите внимание, что свойство Data объекта Path устанавливается в объект GeometryGroup, который содержит объекты других производных от Geometry классов, таких как EllipseGeometry, RectangleGeometry и LineGeometry. Результат представлен на рис.26.3.
Изображение на рис. 26.3 может быть визуализировано с применением показанных ранее классов Line, Ellipse и Rectangle. Однако это потребовало бы помещения различных объектов UIElement в память. Когда для моделирования точек рисуемого изображения используются геометрические объекты, а затем коллекция геометрических объектов помещается в контейнер, который способен визуализировать данные (Path в рассматриваемом случае), то тем самым сокращается расход памяти.
Теперь вспомните, что класс Path имеет ту же цепочку наследования, что и любой член пространства имен System.Windows.Shapes, а потому обладает возможностью отправлять такие же уведомления о событиях, как другие объекты UIElement. Следовательно, если определить тот же самый элемент в проекте Visual Studio, тогда выяснить, что пользователь щелкнул в любом месте линии, можно будет за счет обработки события мыши (не забывайте, что редактор Kaxaml не разрешает обрабатывать события для написанной разметки).
"Мини-язык" моделирования путей
Из всех классов, перечисленных в табл. 26.3, класс PathGeometry наиболее сложен для конфигурирования в терминах XAML и кода. Причина объясняется тем фактом, что каждый PathGeometry состоит из объектов, содержащих разнообразные сегменты и фигуры (скажем, ArcSegment, BezierSegment, LineSegment, PolyBezierSegment, PolyLineSegment, PolyQuadraticBezierSegment и т.д.). Вот пример объекта Path, свойство Data которого было установлено в элемент PathGeometry, состоящий из различных фигур и сегментов:
Point1="100,0"
Point2="200,200"
Point3="300,100"/>
Size="50,50" RotationAngle="45"
IsLargeArc="True" SweepDirection="Clockwise"
Point="200,100"/>