Фигуры
87WPF --- Графика и анимация WPF --- Фигуры
Простейший способ нарисовать двухмерное графическое содержимое в пользовательском интерфейсе WPF заключается в использовании фигур — выделенных классов, представляющих простые линии, эллипсы, прямоугольники и многоугольники. Эти фигуры известны как графические примитивы. Эти базовые ингредиенты можно комбинировать для создания более сложной графики.
Наиболее важная деталь, касающаяся фигур в WPF, состоит в том, что все они наследуются от FrameworkElement. В результате этого фигуры являются элементами. С этим фактом связан ряд важных последствий, которые описаны ниже:
Фигуры рисуют сами себя. Управлять процессом рисования и объявления фигуры недействительной не понадобится. Например, не потребуется вручную перерисовывать фигуру, когда перемещается содержимое, изменяется размер окна или меняются свойства фигур.
Фигуры организованы таким же образом, как и другие элементы. Другими словами, фигуры можно помещать в любой из контейнеров компоновки. (Хотя вполне очевидно, что наиболее полезным контейнером будет Canvas, поскольку он позволяет размещать фигуры по определенным координатам, что важно для построения сложных рисунков, состоящих из множества частей.)
Фигуры поддерживают те же события, что и другие элементы. Это означает, что предпринимать какие-то специальные действия, связанные с обработкой фокуса, нажатий клавиш, перемещений и щелчков кнопками мыши, не потребуется. Можно использовать тот же самый набор событий, что и с любым элементом, и получать аналогичную поддержку всплывающих подсказок, контекстных меню и операций перетаскивания.
Такая модель значительно отличается от моделей, применявшихся в других технологиях построения пользовательских интерфейсов, таких как Windows Forms. Эти среды выполняют большую часть работы с использованием традиционной оконной модели (через User32), которая становится совершенно неэффективной, если ее применять к фрагментам графического содержимого вроде индивидуальных линий и квадратов.
Вдобавок оконная модель требует, чтобы каждый элемент "владел" маленькой частью экрана, что затрудняет реализацию прозрачности и использование сглаживания граней непрямоугольных форм.
Из-за этих ограничений более старые платформы используют для специального рисования низкоуровневую модель GDI/GDI+. Это требует больших усилий и предлагает гораздо меньше высокоуровневых средств.
Возможность низкоуровневого программирования в WPF сохранена — за счет использования визуального уровня. Эта облегченная модель повышает производительность, когда требуется создать огромное количество элементов (скажем, тысячи фигур), и вам не нужны все средства классов UIElement и FrameworkElement (вроде привязки данных и обработки событий). Однако программирование на визуальном уровне работает и на более высоком уровне, чем GDI/GDI+. Важнее всего то, что WPF управляет процессом перерисовки автоматически. Вы просто поставляете содержимое.
Классы фигур
Каждая фигура наследуется от абстрактного класса System.Windows.Shapes.Shape. На рисунке показана иерархия наследования классов фигур:
Как видите, существует относительно небольшой набор классов, унаследованных от класса Shape. Фигуры Line, Ellipse и Rectangle являются простейшими. Polygon состоит из последовательной замкнутой серии соединенных друг с другом отрезков прямых линий. И, наконец, Path — не имеющий себе равных класс "все в одном", который может комбинировать базовые фигуры в едином элементе.
Хотя класс Shape сам по себе не может ничего делать, в нем определен небольшой набор важных свойств, перечисленных ниже:
- Fill
Устанавливает объект кисти, рисующей поверхность фигуры (все, что расположено в ее границах)
- Stroke
Устанавливает объект кисти, рисующей границу фигуры
- StrokeThickness
Устанавливает толщину границы в единицах, независимых от устройства. При рисовании линии WPF разбивает ширину на каждую сторону. Поэтому линия толщиной в 10 единиц получает по 5 единиц пространства с каждой стороны от того места, где проходила бы линия толщиной в одну единицу. Если толщина линии задана нечетным количеством единиц, то на каждую сторону приходится дробное число единиц. Например, линия толщиной 11 единиц имеет по 5,5 единиц пространства на каждую сторону. Это в значительной мере гарантирует, что линия равномерно распределится по пикселям монитора, даже если он работает с разрешением 96 dpi, так что получится слегка расплывчатый, сглаженный контур. Можете воспользоваться свойством SnapsToDevicePixels, чтобы убрать это, если оно вам не по душе
- StrokeStartLineCap, StrokeEndLineCap
Определяют контур краев в начале и конце линии. Эти свойства имеют эффект только для фигур Line, Polyline и (иногда) Path. Все прочие фигуры замкнуты, а потому начальной и конечной точки не имеют
- StrokeDashArray, StrokeDashOffset, StrokeDashCap
Позволяют создавать заштрихованную границу вокруг фигуры. Можно управлять размером и частотой штриховки, а также контуром, ограничивающим начало и конец каждой штриховой линии
- StrokeLineJoin, StrokeMiterLimit
Определяют контур углов фигуры. Технически эти свойства затрагивают вершины, где стыкуются разные линии, такие как углы Rectangle. Эти свойства не имеют эффекта для фигур без углов, подобных Line и Ellipse
- Stretch
Определяет способ заполнения фигурой доступного пространства. Это свойство можно использовать для создания фигуры, которая распространяется на весь содержащий ее контейнер. Можно также принудительно растянуть фигуру по одному измерению, используя значение Stretch для свойств HonzontalAlignment и VerticalAlignment (унаследованных от класса FrameworkElement)
- DefiningGeometry
Предоставляет объект Geometry для фигуры. Объект Geometry описывает координаты и размер фигуры без учета таких вещей из UIElement, как поддержка событий клавиатуры и мыши.
- GeometryTransform
Позволяет применять объект Transform, который изменяет координатную систему, используемую для рисования фигуры. Это дает возможность искажать, вращать или перемещать фигуру. Трансформации, в частности, полезны для анимации.
- RenderedGeometry
Предоставляет объект Geometry, описывающий финальную, визуализированную фигуру.