Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Windows Presentation Foundation.docx
Скачиваний:
43
Добавлен:
02.11.2018
Размер:
1.15 Mб
Скачать

11. Классы drawing и visual

Абстрактный класс System.Windows.Media.Drawing представляет двухмерные рисунки – другими словами, содержит всю информацию, которая нужна для отображения части векторного или битового изображения.

Набор стандартных наследников Drawing перечислен в табл. 10.

Таблица 10

Классы Drawing

Имя класса

Описание

Важные свойства

GeometryDrawing

Обёртывает геометрию заполняющей кистью и пером, очерчивающим контур

Geometry, Brush, Pen

ImageDrawing

Обёртывает графический образ (обычно битовую карту из файла) прямоугольником, определяющим его границы

ImageSource, Rect

VideoDrawing

Комбинирует MediaPlayer, используемый для воспроизведения видео, с прямоугольником, задающим его границы

Player, Rect

GlyphRunDrawing

Обёртывает низкоуровневый текстовый объект, известный как GlyphRun, с кистью, рисующей его

GlyphRun, ForegroundBrush

DrawingGroup

Комбинирует коллекцию объектов Drawing любого типа. DrawingGroup позволяет создавать составные рисунки и применять эф­фекты ко всей коллекции сразу

BitmapEffect, BitmapEffectInput, Children, ClipGeometry, GuidelineSet, Opacity, OpacityMask, Transform

Классы-наследники Drawing не являются элементами, а, значит, не могут быть помещены в пользовательский интерфейс. Для отображения рисунка нужно использовать один из трех классов, перечисленных ниже:

  • DrawingImage – этот класс унаследован от ImageSource и позволяет разместить рисунок внутри элемента Image;

  • DrawingBrush – унаследован от Brush и позволяет обернуть рисунок кистью, которую можно использовать для заполнения любой поверхности;

  • DrawingVisual – унаследован от Visual и позволяет поместить рисунок в низкоуровневый визуальный объект.

Следующий фрагмент разметки демонстрирует создание объекта GeometryDrawing и размещение его в элементе Image, который, в свою очередь, помещён на кнопку.

<Button Height="100" Width="210">

<Image>

<Image.Source>

<DrawingImage>

<DrawingImage.Drawing>

<GeometryDrawing>

<GeometryDrawing.Geometry>

<GeometryGroup>

<EllipseGeometry Center="50,50" RadiusX="45" RadiusY="20"/>

<EllipseGeometry Center="50,50" RadiusX="20" RadiusY="20" />

</GeometryGroup>

</GeometryDrawing.Geometry>

<GeometryDrawing.Brush>

<LinearGradientBrush>

<GradientStop Color="Blue" Offset="0" />

<GradientStop Color="#CCF" Offset="1" />

</LinearGradientBrush>

</GeometryDrawing.Brush>

<GeometryDrawing.Pen>

<Pen Thickness="4" Brush="Black" />

</GeometryDrawing.Pen>

</GeometryDrawing>

</DrawingImage.Drawing>

</DrawingImage>

</Image.Source>

</Image>

</Button>

Рис. 35. Кнопка с изображением, содержащим GeometryDrawing.

В приложениях интенсивной графики, работающих с большим числом графических примитивов, использование фигур, геометрий и рисунков не оправдано с точки зрения производительности. В таких ситуациях следует применять низкоуровневую модель визуального слоя (visual layer). Базовая идея в том, чтобы определить графический элемент как объект Visual, который чрезвычайно облегчён и требует меньших накладных расходов, чем Geometry или Path.

Класс Visual является абстрактным, поэтому используются его классы-наследники. К ним относится UIElement (корень элементной модели WPF), Viewport3DVisual (отображение трёхмерных моделей) и ContainerVisual (базовый контейнер, содержащий другие объекты Visual). Наиболее полезный класс – это DrawingVisual (наследник ContainerVisual), добавляющий поддержку, необходимую для рисования графического содержимого.

Чтобы нарисовать содержимое в DrawingVisual, вызывается его экземплярный метод RenderOpen(). Этот метод возвращает объект DrawingContext. Класс DrawingContext состоит из методов (перечисленных в табл. 11), которые добавляют графические детали к создаваемому визуальному объекту. Завершив рисование, следует вызвать у контекста экземплярный метод Close(). Ниже показан пример создания элемента, содержащего чёрный треугольник:

DrawingVisual visual = new DrawingVisual();

using (DrawingContext dc = visual.RenderOpen())

{

Pen drawingPen = new Pen(Brushes.Black, 3);

dc.DrawLine(drawingPen, new Point(0, 50), new Point(50, 0));

dc.DrawLine(drawingPen, new Point(50, 0), new Point(100, 50));

dc.DrawLine(drawingPen, new Point(0, 50), new Point(100, 50));

}

Фактически, вызов методов DrawingContext не выполняет рисования, а определяет внешний вид визуального элемента. После вызова Close() готовый рисунок доступен только для чтения через свойство DrawingVisual.Drawing.

Таблица 11

Методы класса DrawingContext

Имя метода

Описание

DrawLine(),

DrawRectangle(),

DrawRoundedRectangle(),

DrawEllipse()

Рисует указанную фигуру в указанной точке, с указанным заполнением и контуром

DrawGeometry(),

DrawDrawing()

Рисует объекты Geometry и Drawing

DrawText()

Рисует текст в указанном месте. Детали оформления текста передаются методу в объекте FormattedText

DrawImage()

Рисует битовое изображение в указанной области

DrawVideo()

Рисует видео-содержимое (помещённое в объект MediaPlayer)

Pop()

Отменяет действие последнего вызова метода PushXXX()

PushClip()

Ограничивает рисование определённой областью. Содержимое, выходящее за её пределы, не рисуется

PushEffect()

Применяет BitmapEffect к последующим операциям рисования

PushOpacity(),

PushOpacityMask()

Применяет новые установки прозрачности или маску прозрачности, чтобы сделать последующие операции рисования частично прозрачными

PushTransform()

Устанавливает объект Transform, который будет применён к последующим операциям рисования

Чтобы отобразить визуальный объект, понадобится помощь полноценного элемента WPF, который добавит его в визуальное дерево. Ниже описаны шаги, необходимые для размещения визуальных объектов в элементе.

  • Вызов методов AddVisualChild() и AddLogicalChild() элемента для регистрации визуального объекта. Эти действия не являются необходимыми для того, чтобы визуальные элементы отобразились. Они нужны, чтобы гарантировать корректное отслеживание элементов в визуальном и логическом дереве, а также для взаимодействия с другими средствами WPF, такими как проверка попадания.

  • Переопределение свойства VisualChildrenCount и возврат количества добавленных визуальных объектов.

  • Переопределение метода GetVisualChild() и добавление кода, необходимого для возврата вашего визуального элемента по номеру индекса.

Переопределение VisualChildrenCount и GetVisualChild() выполняет графическое замещение элемента. Например, если вы переопределите эти два метода в пользовательском окне, то не увидите остального содержимого этого окна. Вместо этого вы увидите только добавленные визуальные объекты. По этой причине принято создавать выделенный пользовательский класс, который служит оболочкой для визуальных объектов, которые нужно отобразить.