public static RoutedEvent[]

advertisement
Классы Windows Presentation Foundation - 1
System.Object
DispatcherOject
Application
DependencyObject
Visual
ContentElement
UIElement
FrameworkContentElement
System.Object
System.Windows.Threading.DispatcherObject
System.Windows.DependencyObject
System.Windows.Media.Visual
System.Windows.UIElement
System.Windows.FrameworkElement
System.Windows.Controls.Control
System.Windows.Controls.ItemsControl
System.Windows.Controls.Primitives.Selector
System.Windows.Controls.ComboBox
System.Windows.Controls.ListBox
System.Windows.Controls.TabControl
FrameworkElement
Control
ItemsControl
ContentControl
Window
ButtonBase
Button
CheckBox
Selector
ToggleButton
RadioButton
ListBox
ListView
ComboBox
TreeView
TabControl
MenuBase
Menu
HeaderedItemsControl
ContextMenu
ToolBar
Маршрутизация событий
 Механизм обработки событий WPF базируется на событиях .NET.
 Новая концепция - маршрутизация событий ( event routing) – события могут
подниматься или спускаться по дереву элементов и вызывать обработчики
нескольких слушателей (listeners).
 Три вида событий:
Direct events
(прямые события)
Возникают в одном элементе и не передаются в другие.
Пример – MouseEnter.
Bubbling events
(поднимающиеся,
пузырьковые события )
Начинаются во внутреннем элементе и распространяются во
внешние – от дочернего элемента к родительским. Пример –
MouseDown.
Tunneling events
( туннельные,
туннелированные
события )
Возникают во внешнем элементе и туннелируются во
вложенные элементы – от родительского к дочернему
элементу. Пример (PreviewMouseMove). Все туннелируемые
события в WPF API имеют префикс “Preview” и обычно имеют
соответствующие поднимающиеся события.
 С точки зрения реализации маршрутизируемое событие - это событие,
которое связано с экземпляром класса RoutedEvent, и обрабатывается системой
управления событиями WPF (WPF event system).
Класс 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 регистрирует маршрутизируемые события
(routed event) и добавляет обработчики класса ( class handlers) – обработчик,
который вызывается до вызова обработчиков, связанных с отдельными
экземплярами(объектами) класса.
 В классе всего 4 статических метода.
public static RoutedEvent
RegisterRoutedEvent ( string name,
RoutingStrategy routingStrategy,
Type handlerType,
Type ownerType );
Регистрирует новое маршрутизируемое событие в
системе событий WPF.
public static void
RegisterClassHandler ( Type classType,
RoutedEvent routedEvent,
Delegate handler,
bool handledEventsToo );
Регистрирует обработчик класса для события с опцией
handledEventsToo обработки для событий, которые уже
отмечены как обработанные. Перегружен.
public static RoutedEvent[]
GetRoutedEventsForOwner ( Type ownerType );
Возвращает массив маршрутизируемых событий для
типа-владельца ownerType ( включая базовые классы)
или null, если тип не имеет маршрутизируемых событий.
public static RoutedEvent[]
GetRoutedEvents();
Возвращает массив маршрутизируемых событий,
зарегистрированных в системе событий WPF в текущий
момент. Коллекция содержит все события из
WPF API. В процессе работы приложения коллекция
может измениться.
Метод RegisterRoutedEvent класса EventManager
public static RoutedEvent RegisterRoutedEvent
( string name, RoutingStrategy routingStrategy, Type handlerType, Type ownerType );
 Метод RegisterRoutedEvent регистрирует новое маршрутизируемое
событие в системе управления событиями WPF.
Параметры метода
RegisterRoutedEvent
string name
Имя регистрируемого события. Имя должно быть уникальным в
типе-владельце и не может быть пустой строкой или иметь
значение null.
RoutingStrategy routingStrategy
Значение перечисления System.Windows.RoutingStrategy, которое
определяет стратегию маршрутизации события (routing strategy).
Значения перечисления – Tunnel, Bubble, Direct.
Type handlerType
Тип делегата-обработчика. Это должен быть тип-делегат, значение
null не допускается.
Type ownerType
Тип класса-владельца. Не может иметь значение null.
Return value – объект типа
RoutedEvent
Объект типа RoutedEvent , который можно использовать как статическое
поле класса и как параметр методов при определении обработчиков
событий (подписке на событие).
Пример регистрации маршрутизируемого события
 Маршрутизируемое событие (routed event)
• определяется как статическое поле, доступное только для чтения;
• регистрируется в статическом конструкторе;
• упаковывается как обычное событие .NET.
 Событие инициируется при вызове метода RaiseEvent из любого класса,
производного от FrameworkUIElement.
public class MyButtonSimple : Button
{ public static readonly RoutedEvent TapEvent =
EventManager.RegisterRoutedEvent ( "Tap", RoutingStrategy.Bubble,
typeof(RoutedEventHandler), typeof(MyButtonSimple));
public event RoutedEventHandler Tap
{ add { AddHandler(TapEvent, value); }
remove { RemoveHandler(TapEvent, value);
}
void RaiseTapEvent()
{
RoutedEventArgs newEventArgs = new RoutedEventArgs(MyButtonSimple.TapEvent);
RaiseEvent ( newEventArgs);
}
protected override void OnClick() { RaiseTapEvent(); }
}
Класс RoutedEventArgs
EventArgs
RoutedEventArgs
InputEventArgs
MouseEventArgs
KeyboardEventArgs
KeyboardFocusChangedEventArgs
KeyEventArgs
MouseButtonEventArgs
MouseWheelEventArgs
QueryCursorEventArgs
 Конструкторы класса RoutedEventArgs:
public RoutedEventArgs();
public RoutedEventArgs (
RoutedEvent routedEvent );
public RoutedEventArgs (
RoutedEvent routedEvent,
Object source );
При использовании конструктора без параметров свойства
получают значения по умолчанию: null для RoutedEvent, Source и
OriginalSource и false для Handled.
При вызове метода RaiseEvent() свойствам Source и
OriginalSource будут присвоены ссылки на объект, который
вызвал( raised) событие, эти значения доступны слушателям в
процессе маршрутизации события.
Свойства класса 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; }
Первоначальный источник события, установленный до любого возможного
изменения в процессе обработки.
Обработчик класса для маршрутизируемых событий
 Для маршрутизируемых событий можно определить обработчик класса –
статический обработчик, общий для всех экземпляров класса.
 Обработчики класса вызываются до экземплярных обработчиков.
 Обработчик класса может установить для события состояние
обработанного – присвоить значение true свойству Handled. В этом случае
экземплярные объекты вызываться не будут, за исключением тех, которые
были зарегистрированы со значением true параметра handledEventsToo.
 Многие базовые элементы WPF имеют виртуальные обработчики класса.
Это дает возможность определить свои версии обработчиков класса без
использования вызова метода RegisterClassHandler из статического
конструктора класса. В WPF API эти методы определены для событий ввода,
их имена начинаются с "On" и включают имя события, например, .
События времени существования объекта
 Все объекты классов, производных от FrameworkElement или
FrameworkContentElement, имеют три события времени жизни.
Initialized
Событие времени работы конструктора. При обработке этого события установлены
значения свойств объекта, за исключением динамических ресурсов и привязки
данных.
Событие возникает последовательно по направлению от дочернего к родительским
элементам.
При обработке события следует иметь ввиду, что родительские объекты могут быть
еще не инициализированы и ссылки имеют нулевые значения.
Loaded
Возникает после события Initialized, непосредственно перед экранизацией (rendering).
При этом уже создано логическое дерево элементов и вычислены все размеры и
местоположение элементов. Событие возникает сначала в корневом элементе.
Каждый элемент имеет возможность обработать это событие, значение свойства
Handled не влияет на обработку.
Unloaded
Возникает последним. При обработке события следует иметь ввиду, что
родительские объекты могут быть уже выгружены, и ссылки на объекты привязки,
ресурсы и стили могут быть недействительны.
Элементы-контейнеры
 Класс Window в WPF является производным от класса ContentControl,
разрешающего разместить в окне только один дочерний элемент.
 Чтобы разместить в окне несколько дочерних элементов управления, их
необходимо поместить в один из контейнеров, которые могут быть вложены
друг в друга.
 Классы-контейнеры элементов управления являются производными от
класса Panel.
public abstract class Panel : FrameworkElement, IAddChild {…}
public interface IAddChild
{
void AddChild( Object value );
void AddText( string text );
}
public UIElementCollection Children { get; }
Download