Язык программирования C#9 и платформа .NET5
• Визуальные объекты. Самый быстрый и легковесный способ визуализации графических данных в WPF предусматривает работу с визуальным уровнем, который доступен только через код С#. С применением классов, производных от
, можно взаимодействовать непосредственно с графической подсистемой WPF.System.Windows.Media.VisualПричина предоставления разных способов решения той же самой задачи (т.е. визуализации графических данных) связана с расходом памяти и в конечном итоге с производительностью приложения. Поскольку WPF является системой, интенсивно использующей графику, нет ничего необычного в том, что приложению требуется визуализировать сотни или даже тысячи различных изображений на поверхности окна, и выбор реализации (фигуры, рисунки или визуальные объекты) может оказать огромное влияние.
Важно понимать, что при построении приложения WPF высока вероятность использования всех трех подходов. В качестве эмпирического правила запомните: если нужен умеренный объем интерактивных графических данных, которыми может манипулировать пользователь (принимающих ввод от мыши, отображающих всплывающие подсказки и т.д.), то следует применять члены из пространства имен
.System.Windows.ShapesНапротив, рисунки и геометрические объекты лучше подходят, когда необходимо моделировать сложные и по большей части не интерактивные векторные графические данные с использованием разметки XAML или кода С#. Хотя рисунки и геометрические объекты способны реагировать на события мыши, а также поддерживают проверку попадания и операции перетаскивания, для выполнения таких действий обычно приходится писать больше кода.
Наконец, если требуется самый быстрый способ визуализации значительных объемов графических данных, то должен быть выбран визуальный уровень. Например, предположим, что инфраструктура WPF применяется для построения научного приложения, которое должно отображать тысячи точек на графике данных. За счет использования визуального уровня точки на графике можно визуализировать оптимальным образом. Как будет показано далее в главе, визуальный уровень доступен только из кода С#, но не из разметки XAML.
Независимо от выбранного подхода (фигуры, рисунки и геометрические объекты или визуальные объекты) всегда будут применяться распространенные графические примитивы, такие как кисти (для заполнения ограниченных областей), перья (для рисования контуров) и объекты трансформаций (которые видоизменяют данные). Исследование начинается с классов из пространства имен
.System.Windows.ShapesНа заметку! Инфраструктура WPF поставляется также с полнофункциональным API-интерфейсом, который можно использовать для визуализации и манипулирования трехмерной графикой, но в книге он не рассматривается.
Визуализация графических данных с использованием фигур
Члены пространства имен
предлагают наиболее прямолинейный, интерактивный и самый затратный в плане расхода памяти способ визуализации двумерного изображения. Это небольшое пространство имен (расположенное в сборкеSystem.Windows.Shapes) состоит всего из шести запечатанных классов, которые расширяют абстрактный базовый классPresentationFramework.dll:Shape,Ellipse,Rectangle,Line,PolygonиPolyline.PathАбстрактный класс
унаследован от классаShape, который сам унаследован отFrameworkElement. В указанных классах определены члены для работы с изменением размеров, всплывающими подсказками, курсорами мыши и т.п. Благодаря такой цепочке наследования при визуализации графических данных с применением классов, производных отUIElement, объекты получаются почти такими же функциональными (с точки зрения взаимодействия с пользователем), как элементы управления WPF.ShapeСкажем, для выяснения, щелкнул ли пользователь на визуализированном изображении, достаточно обработать событие
. Например, если написать следующую разметку XAML для объектаMouseDownвнутри элемента управленияRectangleначального окнаGrid:Window<Rectangle x:Name="myRect" Height="30" Width="30" Fill="Green"MouseDown="myRect_MouseDown"/>то можно реализовать обработчик события
, который изменяет цвет фона прямоугольника в результате щелчка на нем:MouseDownprivate void myRect_MouseDown(object sender, MouseButtonEventArgs e){// Изменить цвет прямоугольника в результате щелчка на нем.myRect.Fill = Brushes.Pink;}В отличие от других инструментальных наборов, предназначенных для работы с графикой, вам не придется писать громоздкий код инфраструктуры, в котором вручную сопоставляются координаты мыши с геометрическим объектом, выясняется попадание курсора внутрь границ, выполняется визуализация в неотображаемый буфер и т.д. Члены пространства имен
просто реагируют на зарегистрированные вами события подобно типичному элементу управления WPF (System.Windows.Shapesи т.д.).ButtonНедостаток всей готовой функциональности связан с тем, что фигуры потребляют довольно много памяти. Если строится научное приложение, которое рисует тысячи точек на экране, то использование фигур будет неудачным выбором (по существу таким же расточительным в плане памяти, как визуализация тысяч объектов
). Тем не менее, когда нужно сгенерировать интерактивное двумерное векторное изображение, фигуры оказываются прекрасным вариантом.ButtonПомимо функциональности, унаследованной от родительских классов
иUIElement, в классеFrameworkElementопределено множество собственных членов, наиболее полезные из которых кратко описаны в табл. 26.1.ShapeНа заметку! Если вы забудете установить свойства
иFill, то WPF предоставит "невидимые" кисти, вследствие чего фигура не будет видна на экране!StrokeДобавление прямоугольников, эллипсов и линий на поверхность Canvas
Вы построите приложение WPF, которое способно визуализировать фигуры, с применением XAML и С#, и попутно исследуете процесс проверки попадания. Создайте новый проект приложения WPF по имени
и измените заголовок главного окна вRenderingWithShapesнаMainWindow.xaml. Модифицируйте первоначальную разметку XAML для элементаFun with Shapes!, заменивWindowпанельюGrid, которая содержит (пока пустые) элементыDockPanelиToolbar. Обратите внимание, что каждому содержащемуся элементу посредством свойстваCanvasназначается подходящее имя.Name
