事件
事件的前身是消息(在窗体点左键会生成一条携带参数的消息加入windows待处理消息队列,当windows处理到这条消息时会把其发给窗体,窗体再用自己的消息处理函数进行响应)。
消息封装成事件模型后得到简化,只需关注事件的拥有者、响应者、订阅关系(如A订阅了B的事件,即B.Event
和A.EventHandler
存在绑定关系),本质上是一个用event
关键字修饰了的委托实例。
在CLR直接事件模型中,事件的拥有者就是消息的发送者。
路由事件是WPF提供的事件机制,用于弥补直接事件的以下缺陷
- 每对事件都要单独进行显示绑定
- 事件宿主必须能够访问事件响应者以建立订阅关系
路由事件的拥有者和响应者之间没用显示订阅关系,订阅者只负责激发事件,由响应者决定要侦听的事件。
WPF中的事件大多为可路由事件,
<Grid x:Name="myGrid" Button.Click="ButtonClicked">
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Button x:Name="myButton" Grid.Column="0" Grid.Row="1" Content="Click Me"></Button>
</Grid>
...
public partial class Event : Window
{
public Event()
{
InitializeComponent();
//也可以不用Button.Click="ButtonClicked"而直接在逻辑中定义
//myGrid.AddHandler(Button.ClickEvent,new RoutedEventHandler(ButtonClicked));
}
private void ButtonClicked(object sender,RoutedEventArgs e)
{
//与直接事件不同,此处sender是grid而非button,需通过e.OriginalSource查看事件源头
MessageBox.Show((e.OriginalSource as FrameworkElement).Name);
}
}
此外还有自定义路由事件,可自定义冒泡方式(气泡、隧道和直接)。
命令 Command
由事件的触发源控制接收者如何进行工作,默认左单击为执行命令的时机。
网友评论