Реагирование на операции проверки попадания
Поскольку класс DrawingVisual не располагает инфраструктурой UIElement или FrameworkElement, необходимо программно добавить возможность реагирования на операции проверки попадания. Благодаря концепции логического и визуального деревьев на визуальном уровне делать это очень просто. Оказывается, что в результате написания блока XAML по существу строится логическое дерево элементов. Однако с каждым логическим деревом связано намного более развитое описание, известное как визуальное дерево, которое содержит низкоуровневые инструкции визуализации.
Упомянутые деревья подробно рассматриваются в главе 27, а сейчас достаточно знать, что до тех пор, пока специальные визуальные объекты не будут зарегистрированы в таких структурах данных, выполнять операции проверки попадания невозможно. К счастью, контейнер VisualCollection обеспечивает регистрацию автоматически (вот почему в аргументе конструктора необходимо передавать ссылку на специальный элемент FrameworkElement).
Измените код класса CustomVisualFrameworkElement для обработки события MouseDown в конструкторе класса с применением стандартного синтаксиса С#:
this.MouseDown += CustomVisualFrameworkElement_MouseDown;
Реализация данного обработчика будет вызывать метод VisualTreeHelper.HitTest() с целью выяснения, находится ли курсор мыши внутри границ одного из визуальных объектов. Для этого в одном из параметров метода HitTest() указывается делегат HitTestResultCallback, который будет выполнять вычисления. Добавьте в класс CustomVisualFrameworkElement следующие методы:
void CustomVisualFrameworkElement_MouseDown(object sender, MouseButtonEventArgs e)
{
<b> // Выяснить, где пользователь выполнил щелчок.</b>
Point pt = e.GetPosition((UIElement)sender);
<b> // Вызвать вспомогательную функцию через делегат, чтобы</b>
<b> // посмотреть, был ли совершен щелчок на визуальном объекте.</b>
VisualTreeHelper.HitTest(this, null,
new HitTestResultCallback(myCallback), new PointHitTestParameters(pt));
}
public HitTestResultBehavior myCallback(HitTestResult result)
{
<b> // Если щелчок был совершен на визуальном объекте, то</b>
<b> // переключиться между скошенной и нормальной визуализацией.</b>
if (result.VisualHit.GetType() == typeof(DrawingVisual))
{
if (((DrawingVisual)result.VisualHit).Transform == null)
{
((DrawingVisual)result.VisualHit).Transform = new SkewTransform(7, 7);
}
(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})
else
{
((DrawingVisual)result.VisualHit).Transform = null;
}
}
<b> // Сообщить методу HitTest() о прекращении углубления в визуальное дерево.</b>
return HitTestResultBehavior.Stop;
}
Снова запустите программу. Теперь должна появиться возможность щелкать на любом из отображенных визуальных объектов и наблюдать за выполнением трансформации. Наряду с тем, что рассмотренный пример взаимодействия с визуальным уровнем WPF очень прост, не забывайте, что здесь можно использовать те же самые кисти, трансформации, перья и диспетчеры компоновки, которые обычно применяются в разметке XAML. Таким образом, вы уже знаете довольно много о работе с классами, производными от Visual.
На этом исследование служб графической визуализации WPF завершено. Несмотря на раскрытие ряда интересных тем, на самом деле мы лишь слегка затронули обширную область графических возможностей инфраструктуры WPF. Дальнейшее изучение фигур, рисунков, кистей, трансформаций и визуальных объектов вы можете продолжить самостоятельно (в оставшихся главах, посвященных WPF, еще встретятся дополнительные детали).
Резюме
Поскольку Windows Presentation Foundation является настолько насыщенной графикой инфраструктурой для построения графических пользовательских интерфейсов, не должно вызывать удивления наличие нескольких способов визуализации графического вывода. Плава начиналась с рассмотрения трех подходов к визуализации (фигуры, рисунки и визуальные объекты ), а также разнообразных примитивов визуализации, таких как кисти, перья и трансформации.
Вспомните, что когда необходимо строить интерактивную двумерную визуализацию, то фигуры делают такой процесс очень простым. С другой стороны, статические, не интерактивные изображения могут визуализироваться в оптимальной манере с использованием рисунков и геометрических объектов, а визуальный уровень (доступный только в коде) обеспечит максимальный контроль и производительность.
Глава 27
Ресурсы, анимация, стили и шаблоны WPF
В настоящей главе будут представлены три важные (и взаимосвязанные) темы, которые позволят углубить понимание API-интерфейса Windows Presentation Foundation (WPF). Первым делом вы изучите роль логических ресурсов. Вы увидите, что система логических ресурсов (также называемых объектными ресурсами) представляет собой способ ссылки на часто используемые объекты внутри приложения WPF. Хотя логические ресурсы нередко реализуются в разметке XAML, они могут быть определены и в процедурном коде.
Далее вы узнаете, как определять, выполнять и управлять анимационной последовательностью. Вопреки тому, что можно было подумать, применение анимации WPF не ограничивается видеоиграми или мультимедийными приложениями. В API-интерфейсе WPF анимация может использоваться, например, для подсветки кнопки, когда она получает фокус, или увеличения размера выбранной строки в DataGrid. Понимание анимации является ключевым аспектом построения специальных шаблонов элементов управления (как вы увидите позже в главе).
Затем объясняется роль стилей и шаблонов WPF. Подобно веб-странице, в которой применяются стили CSS или механизм тем ASP.NET, приложение WPF может определять общий вид и поведение для набора элементов управления. Такие стили можно определять в разметке и сохранять их в виде объектных ресурсов для последующего использования, а также динамически применять во время выполнения. В последнем примере вы научитесь строить специальные шаблоны элементов управления.