Далее будет построена небольшая программа, иллюстрирующая основы использования визуального уровня.
Базовый класс Visual и производные дочерние классы
Абстрактный класс
System.Windows.Media.Visual
предлагает минимальный набор служб (визуализацию, проверку попадания, трансформации) для визуализации графики, но не предоставляет поддержку дополнительных невизуальных служб, которые могут приводить к разбуханию кода (события ввода, службы компоновки, стили и привязка данных). Класс
Visual
является абстрактным базовым классом. Для выполнения действительных
операций визуализации должен применяться один из его производных классов. В WPF определено несколько подклассов Visual, в том числе
DrawingVisual
,
Viewport3DVisual
и
ContainerVisual
.
Рассматриваемый ниже пример сосредоточен только на
DrawingVisual
— легковесном классе рисования, который используется для визуализации фигур, изображений или текста.
Первый взгляд на класс DrawingVisual
Чтобы визуализировать данные на поверхности с применением класса
DrawingVisual
, понадобится выполнить следующие основные шаги:
• получить объект
DrawingContext
из
DrawingVisual
;
• использовать объект
DrawingContext
для визуализации графических данных.
Эти два шага представляют абсолютный минимум, необходимый для визуализации каких-то данных на поверхности. Тем не менее, когда нужно, чтобы визуализируемые графические данные реагировали на вычисления при проверке попадания (что важно для добавления взаимодействия с пользователем), потребуется также выполнить дополнительные шаги:
• обновить логическое и визуальное деревья, поддерживаемые контейнером, на котором производится визуализация;
• переопределить два виртуальных метода из класса
FrameworkElement
, позволив контейнеру получать созданные визуальные данные.
Давайте исследуем последние два шага более подробно. Чтобы продемонстрировать применение класса
DrawingVisual
для визуализации двумерных данных, создайте в Visual Studio новый проект приложения WPF по имени
RenderingWithVisuals
. Первой целью будет использование класса
DrawingVisual
для динамического присваивания данных элементу управления
Image
из WPF. Начните со следующего обновления разметки XAML окна для обработки события
Loaded
:
<Window x:Class="RenderingWithVisuals.MainWindow"
<!--omitted for brevity -->
Title="Fun With Visual Layer" Height="450" Width="800"
// Создать объект DrawingVisual и получить объект DrawingContext.
DrawingVisual drawingVisual = new DrawingVisual;
using(DrawingContext drawingContext =
drawingVisual.RenderOpen)
{
// Вызвать любой из методов DrawingContext для визуализации данных.
drawingContext.DrawRoundedRectangle(
Brushes.Yellow, new Pen(Brushes.Black, 5),
new Rect(5, 5, 450, 100), 20, 20);
drawingContext.DrawText(text, new Point(20, 20));
}
// Динамически создать битовое изображение,
// используя данные в объекте DrawingVisual.
RenderTargetBitmap bmp = new RenderTargetBitmap(
500, 100, 100, 90, PixelFormats.Pbgra32);
bmp.Render(drawingVisual);
// Установить источник для элемента управления Image.
myImage.Source = bmp;
}
В коде задействовано несколько новых классов WPF, которые будут кратко описаны ниже. Метод начинается с создания нового объекта
FormattedText
, который представляет текстовую часть конструируемого изображения в памяти. Как видите, конструктор позволяет указывать многочисленные атрибуты, в том числе размер шрифта, семейство шрифтов, цвет переднего плана и сам текст.