本文介绍
1.路由策略
2.冒泡事件
3.隧道事件
4.直接事件
5.自定义事件
路由策略
WPF路由事件的策略分为以下三种
1、冒泡事件,指定为RoutingStrategy.Bubble
2、隧道事件,指定为RoutingStrategy.Tunnel
3、直接事件,指定为RoutingStrategy.Direct
冒泡事件(RoutingStrategy.Bubble)
路由事件会依次向上路由到后续的父级元素,直到到达元素树的根,或者在某一个控件中该事件被消费时停止向上路由。
比如如下代码:
<Grid MouseDown="Grid_MouseDown" Background="AliceBlue">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<ComboBox Grid.Row="0" SelectedIndex="0" x:Name="HandleTypeName" DisplayMemberPath="Title" ItemsSource="{Binding HandleTypeList}" SelectionChanged="ComboBox_SelectionChanged" VerticalAlignment="Top"/>
<TextBlock Grid.Row="1" Text="This is Block" Width="200" Height="100" Background="Red" MouseDown="BlockMouseDown"/>
</Grid>
MouseDown响应顺序为BlockMouseDown->Grid_MouseDown,
如果在BlockMouseDown在该事件处理中设置e.Handled=true,那么
Grid_MouseDown事件不响应
隧道事件(RoutingStrategy.Tunnel)
该事件传递顺序和冒泡事件相反,该事是从父控件依次传递到子控件。隧道事件也就是控件事件中以Preview开头的事件。
如上代码MouseDown响应顺序为Grid_MouseDown->BlockMouseDown
如果在Grid_MouseDown在该事件处理中设置e.Handled=true,那么
BlockMouseDown事件不响应
直接事件(RoutingStrategy.Direct)
只传递一层。它源自一个元素,并且不传递给其他元素,MouseEnter事件(当鼠标指针移动到元素上时发生)是直接路由事件。
<StackPanel Orientation="Vertical" MouseEnter="StackMouseEnter" Background="Yellow">
<TextBlock Text="Block鼠标移进来" Background="AliceBlue" Height="50" Width="100" MouseEnter="BlockMouseEnter" />
</StackPanel>
以上代码,鼠标移到TextBlock的时候会响应BlockMouseEnter事件,但是不会响应StackMouseEnter事件。
自定义事件
我们以自定义一个用户控件RouteUserControl,添加一个OnClickEvent点击事件来演示,RouteUserControl.xaml如下
<Border BorderBrush="Green" BorderThickness="1" Padding="5">
<Grid MouseLeftButtonUp="Grid_MouseLeftButtonUp">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="点击我" FontSize="22"/>
<TextBlock Grid.Row="1" Text="Summary" FontSize="16"/>
</Grid>
</Border>
RouteUserControl.cs中发送OnClickEvent事件代码如下
private void Grid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
e.Handled = true;
OnClickEventArgs args = new OnClickEventArgs(OnClickEvent, this)
{
Title = "This is OnClickEvent..."
};
RaiseEvent(args);
}
自定义一个冒泡事件步骤如下
1、定义事件参数
public class OnClickEventArgs : RoutedEventArgs
{
public OnClickEventArgs(RoutedEvent routedEvent, object source) : base(routedEvent, source)
{
}
public string Title { get; set; }
}
2、定义事件
public event EventHandler<OnClickEventArgs> OnClick
{
add => AddHandler(OnClickEvent, value);
remove => RemoveHandler(OnClickEvent, value);
}
3、注册事件
public static readonly RoutedEvent OnClickEvent = EventManager.RegisterRoutedEvent("OnClick", RoutingStrategy.Bubble,
typeof(EventHandler<OnClickEventArgs>),
typeof(RouteUserControl)
);
4、发送事件
OnClickEventArgs args = new OnClickEventArgs(OnClickEvent, this)
{
Title = "This is OnClickEvent..."
};
RaiseEvent(args);
5、响应事件
xaml文件中定义
<local:RouteUserControl OnClick="RouteUserControl_OnClick"/>
cs文件中实现
private void RouteUserControl_OnClick(object sender, OnClickEventArgs e)
{
MessageBox.Show("收到:"+e.Title);
}
参考Demo-RouteWindow
https://blog.csdn.net/weixin_50179284/article/details/121763923