Давайте исследуем последние два шага более подробно. Чтобы продемонстрировать применение класса DrawingVisual
для визуализации двумерных данных, создайте в Visual Studio новый проект приложения WPF по имени RenderingWithVisuals
. Первой целью будет использование класса DrawingVisual
для динамического присваивания данных элементу управления Image
из WPF. Начните со следующего обновления разметки XAML окна для обработки события Loaded
:
Title="Fun With Visual Layer" Height="450" Width="800"
Loaded="MainWindow_Loaded">
Замените элемент Grid
панелью StackPanel
и добавьте в нее элемент Image
:
Элемент управления Image
пока не имеет значения в свойстве Source
, т.к. оно будет устанавливаться во время выполнения. С событием Loaded
связана работа по построению графических данных в памяти с применением объекта DrawingBrush
. Удостоверьтесь в том, что файл MainWindow.cs
содержит операторы using для следующих пространств имен:
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
Вот реализация обработчика события Loaded
:
private void MainWindow_Loaded(
object sender, RoutedEventArgs e)
{
const int TextFontSize = 30;
// Создать объект System.Windows.Media.FormattedText.
FormattedText text = new FormattedText(
"Hello Visual Layer!",
new System.Globalization.CultureInfo("en-us"),
FlowDirection.LeftToRight,
new Typeface(this.FontFamily, FontStyles.Italic,
FontWeights.DemiBold, FontStretches.UltraExpanded),
TextFontSize,
Brushes.Green,
null,
VisualTreeHelper.GetDpi(this).PixelsPerDip);
// Создать объект 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
, который представляет текстовую часть конструируемого изображения в памяти. Как видите, конструктор позволяет указывать многочисленные атрибуты, в том числе размер шрифта, семейство шрифтов, цвет переднего плана и сам текст.
Затем через вызов метода RenderOpen()
на экземпляре DrawingVisual
получается необходимый объект DrawingContext
. Здесь в DrawingVisual
визуализируется цветной прямоугольник со скругленными углами, за которым следует форматированный текст. В обоих случаях графические данные помещаются в DrawingVisual
с применением жестко закодированных значений, что не слишком хорошо в производственном приложении, но вполне подходит для такого простого теста.
Несколько последних операторов отображают DrawingVisual
на объект RenderTagetBitmap
, который является членом пространства имен System.Windows.Media.Imaging
. Этот класс принимает визуальный объект и трансформирует его в растровое изображение, находящееся в памяти. Затем устанавливается свойство Source
элемента управления Image
и получается вывод, показанный на рис. 26.14.