WPF 的采取了路由事件机制,这样事件可以在可视树上层级传递。要知道 XAML 中控件都是由很多其他元素组合而成,比如我们单击了 Button 内部的 TextBlock 元素,Button 依然可以可以接收到该事件并触发 Button.Click。通常情况下,我们只是关心逻辑树上的事件过程。
1)创建
public abstract class ButtonBase : ContentControl, ICommandSource
{
public static readonly RoutedEvent ClickEvent;
static ButtonBase()
{
ClickEvent = EventManager.RegisterRoutedEvent("Click", RoutingStrategy.Bubble,
typeof(RoutedEventHandler), typeof(ButtonBase));
......
}
public event RoutedEventHandler Click
{
add { base.AddHandler(ClickEvent, value); }
remove { base.RemoveHandler(ClickEvent, value); }
}
}
2)类型
注册路由事件时,我们可以选择不同的路由策略。
管道传递(Tunneling): 事件首先在根元素上触发,然后向下层级传递,直到那个最初触发事件的子元素。
冒泡(Bubbling): 事件从最初触发事件的子元素向根元素层级往上传递。
直接(Direct): 事件仅在最初触发事件的子元素上触发。
<Border MouseRightButtonDown="MouseRightButtonDown" >
<StackPanel MouseRightButtonDown="MouseRightButtonDown">
<Button MouseRightButtonDown="MouseRightButtonDown" >Test</Button>
</StackPanel>
</Border>
当点击Button,弹出三个对话框,在按钮上单击右键后,你会依次看到显示 "Button"、"StackPanel"、"Border" 的三个对话框,显然事件按照冒泡向根元素传递。
通常情况下,WPF 控件会在管道事件的名称前添加 Preview 前缀。
3)附加事件
、和附加属性类似,WPF 允许我们在一个没有定义事件的元素上处理经管道或冒泡传递的路由事件。
4) Routed Events主要为键盘,鼠标等输入设备准备的。
Routed Commands包括:
ApplicationCommands, which contains things like Cut/Copy/Paste.
MediaCommands, which contains things like BoostBass/ChannelUp/ChannelDown/MuteVolume.
NavigationCommands, which contains things like BrowseBack/BrowseForward/Favorites.
ComponentCommands, which contains things like MoveDown/MoveFocusPageUp/MoveToEnd.
EditingCommands, which contains things like AlignCenter/Backspace/Delete.