10_Березина_Routed_Events_Base

advertisement
Классы Windows Presentation Foundation
System.Object
DispatcherObject
Application
DependencyObject
NavigationService
FrameworkTemplate
Visual
ContentElement
UIElement
FrameworkContentElement
Style
FrameworkElement
Page
Shape
TextBlock
ContentControl
RangeBase
TextBoxBase
Frame
Slider
TextBox
Window
ProgressBar
RichTextBox
Grid
ItemsControl
Menu
ContextMenu
HeaderedItemsControl
MenuItem
Button
Toolbar
TreeViewItem
Selector
RepeatButton
TabControl
ToggleButton
CheckBox
Canvas
MenuBase
NavigationWindow
ButtonBase
Panel
ToolBarTray
Control
RadioButton
ListBox
ListView
TreeView
ComboBox
Маршрутизированные события (routed events)
 Механизм обработки событий WPF базируется на событиях .NET.
 Новая концепция - маршрутизация событий ( event routing) – события могут подниматься
или спускаться по дереву элементов и вызывать обработчики нескольких слушателей
(listeners).
 Три вида событий:
Direct events
(прямые события)
Возникают в одном элементе и не передаются в другие.
Пример – MouseEnter.
Bubbling events
(поднимающиеся,
пузырьковые события )
Начинаются во внутреннем элементе и распространяются во
внешние – от дочернего элемента к родительским. Пример –
MouseDown.
Tunneling events
( туннельные,
туннелированные
события )
Возникают во внешнем элементе и туннелируются во
вложенные элементы – от родительского к дочернему
элементу. Пример - PreviewMouseMove. Все туннелируемые
события в WPF API имеют префикс “Preview” и обычно имеют
соответствующие пузырьковые события.
 С точки зрения реализации маршрутизируемое событие (routed event) - это событие,
которое связано с экземпляром класса RoutedEvent, и обрабатывается системой
управления событиями WPF (WPF event system).
 Статический класс EventManager регистрирует маршрутизируемые события.
Логическое и визуальное дерево элементов
 WPF использует понятия логического и визуального деревьев для определения связей
между элементами приложения.
 Логическое дерево элементов WPF базируется на отношении дочерний-родительский и
создается при установке значений для свойств, которые представляют модель
содержимого элемента, например, значений свойства Content для элементов Button,
свойства Items для ListBox или Children для классов Panel (явно в коде или неявно на
основе вложенности элементов в разметке).
 Свойство Parent класса FrameworkElement доступно только для чтения и возвращает
логический родительский элемент для данного элемента:
public DependencyObject Parent { get; }
 Логическое дерево используется при поиске объектного ресурса в словарях ресурсов.
 Во время выполнения приложения каждый из элементов логического дерева обычно
расширяется в более сложное дерево визуальных элементов.
 Маршруты событий обычно проходят по визуальному дереву и могут обрабатываться
элементами управления, которые реализуют композицию на визуальном уровне.
Классы LogicalTreeHelper и VisualTreeHelper
 WPF поддерживает классы LogicalTreeHelper и VisualTreeHelper для прохождения по
логическому и визуальному деревьям.
 Для прохода по логическому дереву приложения в программных сценариях
разработчики WPF не рекомендуют использовать класс LogicalTreeHelper, так как
структура логического дерева доступна через API-интерфейсы коллекций элементов
управления.
 Визуальное дерево может использоваться в приложениях, контролирующих процесс
рисования на нижнем уровне с целью оптимизации. В этих случаях удобен класс
VisualTreeHelper.
 В классе LogicalTreeHelper определены статические методы для прохождения по
логическому дереву ( методы-оболочки для вызова свойств из классов FrameworkElement
и FrameworkContentElement ) :
public static DependencyObject GetParent( DependencyObject current );
public static IEnumerable GetChildren( DependencyObject current );
 Класс VisualTreeHelper содержит статические методы для прохождения по визуальному
дереву :
public static DependencyObject GetParent( DependencyObject reference ) ;
public static int GetChildrenCount( DependencyObject reference );
public static DependencyObject GetChild( DependencyObject reference, int childIndex );
TreeView
 TreeView - элемент управления для отображения иерархических данных в виде дерева с
элементами, которые можно разворачивать и сворачивать.
 Класс TreeView наследует ItemsControl. Содержит коллекцию элементов, которая
доступна через свойство Items.
public ItemCollection Items { get; }
 Элементами коллекции в TreeView являются обекты TreeViewItem.
 Класс TreeViewItem наследует HeaderedItemsControl. Каждый элемент TreeViewItem
также поддерживает коллекцию элементов, которая доступна через его свойство Items.
 Свойство Header определяет объект, который выводится в соответствующем узле
дерева при отрисовке TreeView. Заголовок может быть строкой или элементом управления
UIElement.
public Object Header { get; set; }
 От значения булевского свойства IsExpanded зависит, будет ли ветвь дерева развернута
при выводе. Умолчание false.
public bool IsExpanded { get; set; }
Маршрутизация событий
 Прямые события ведут себя как обычные события в .NET Framework. Единственный
потенциальный обработчик для события - делегат, прикрепленный к событию.
 При пузырьковой маршрутизации событие распространяется вверх по визуальному
дереву от исходного элемента до тех пор, пока не будет обработано или не достигнет
корневого элемента.
 Туннельные события начинаются на корневом элементе и передвигаются вниз по
дереву элементов, пока не будут обработаны или не достигнут исходного элемента для
события.
 Маршрутизация не завершается при вызове обработчика события. Чтобы остановить
пузырьковый или туннельный процесс, необходимо в обработчике события явно указать,
что событие обработано, присвоив свойству Handled значение true.
private void MouseDown_Handler (object sender, MouseButtonEventArgs e)
{
textBlock1.Text += "\n" + sender.ToString();
e.Handled = true;
}
Класс RoutedEvent
 Класс RoutedEvent представляет маршрутизируемое событие. В классе определены
четыре свойства и один метод.
 Все свойства доступны только для чтения, свои значения они получают при регистрации
события с помощью метода RegisterRoutedEvent класса EventManager. Свойства не могут
иметь значение null.
public Type HandlerType
Тип делегата-обработчика события.
{ get; }
public string Name
{ get; }
Имя маршрутизируемого события должно быть уникальным внутри
каждого типа-владельца, глобальной уникальности имени не
требуется.
public Type OwnerType
{ get; }
Тип – владелец события. Если событие имеет дополнительных
владельцев (owners added), свойство возвращает первого
объявленного владельца.
public RoutingStrategy
RoutingStrategy { get; }
Значение перечисления System.Windows.RoutingStrategy, которое
определяет стратегию маршрутизации события (routing strategy), –
Tunnel, Bubble или Direct.
public RoutedEvent
AddOwner
( Type ownerType );
Добавляет новый класс к владельцам события. Возвращаемое
значение используется при определении статического поля,
представляющее маршрутизируемое событие в новом классевладельце.
Класс EventManager
 Статический класс EventManager регистрирует маршрутизируемые события и
предоставляет информацию о зарегистрированных событиях в системе событий WPF.
 В классе всего 4 статических метода:
• RegisterRoutedEvent для регистрации маршрутизируемого события;
• RegisterClassHandler для регистрации обработчика класса - обработчика, который
вызывается до вызова экземплярных обработчиков.
• GetRoutedEventsForOwner – метод, возвращающий массив маршрутизируемых
событий для типа-владельца;
• GetRoutedEvents - метод, возвращающий массив всех маршрутизируемых событий,
зарегистрированных в системе событий WPF в текущий момент.
Метод RegisterRoutedEvent класса EventManager
 Метод RegisterRoutedEvent регистрирует новое маршрутизируемое событие в системе
управления событиями WPF.
public static RoutedEvent RegisterRoutedEvent (
string name,
RoutingStrategy routingStrategy,
Type handlerType,
Type ownerType );
 При регистрации необходимо указать
• имя события (string name);
• стратегию маршрутизации (RoutingStrategy routingStrategy);
• тип делегата-обработчика (Type handlerType);
• тип-владелец (Type ownerType).
 Перечисление RoutingStrategy, которое определяет стратегию маршрутизации, может
принимать значения Tunnel, Bubble, Direct.
 Параметры не могут иметь значение null.
 Метод возвращает ссылку на объект типа RoutedEvent, который используется как
статическое поле класса и как параметр методов при определении обработчиков событий.
Свойства класса RoutedEventArgs
 Свойства класса RoutedEventArgs доступны в обработчиках маршрутизируемых
событий.
public RoutedEvent
RoutedEvent
{ get; set; }
Значение RoutedEvent, связанное с экземпляром RoutedEventArgs.
Значение нельзя изменить в процессе обработки события - будет
брошено исключение InvalidOperationException.
Значение свойства не может иметь значение null.
public Object Source
{ get; set; }
Ссылка на объект, который является источником события.
При изменении значения свойства Source свойство OriginalSource
сохраняет ссылку на объект, который вызвал метод RaiseEvent.
public bool Handled
{ get; set; }
Состояние события. Значение по умолчанию равно false. Значение
true указывает, что событие уже было обработано в процессе
маршрутизации.
Когда свойство получает значение true, событие продолжает движение
по маршруту обработки, но будут вызваны только те обработчики, у
которых значение свойства HandledEventsToo равно true.
public Object
OriginalSource
{ get; }
Первоначальный источник события, установленный до любого
возможного изменения в процессе обработки.
Download