事件学习二--自定义路由事件

WPF中有2种树,一种叫做逻辑树(LogicalTree),另一种叫可视元素树(VisualTree),逻辑树是可视元素树的一棵子树,路由事件沿着VisualTree传递。

路由事件的事件拥有者和事件响应者之间没有直接显示的订阅关系,事件的拥有者只负责激发事件,事件由谁响应并不知道,事件的响应者则安装事件监听器,针对某类事件进行侦听,尽管WPF推出路由事件机制,但它仍然支持传统的直接事件模型。

WPF内置的路由事件

<Grid Name="gridRoot">
        <Grid x:Name="gridA">
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Canvas Name="canvasLeft" >
                <Button x:Name="leftbtn" Content="left" Width="120" Height="25"/>
            </Canvas>
            <Canvas Name="canvasRight" Grid.Column="1" >
                <Button x:Name="rightbtn" Content="right" Width="120" Height="25"/>
            </Canvas>
        </Grid>        
    </Grid>
View Code
 public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.gridRoot.AddHandler(Button.ClickEvent, new RoutedEventHandler(this.ButtonClicked));
        }
        private void ButtonClicked(object sender,RoutedEventArgs e)
        {
            MessageBox.Show((e.OriginalSource as FrameworkElement).Name);
        }
    }
View Code

由于所有的WPF事件参数类继承自RoutedEventArgs,因此任何事件处理程序都可以使用以下属性。

  • Source:表示LogicalTree上的消息源头。
  • OriginalSource:表示VisualTree上的源头
  • Handled:该属性允许终止事件的冒泡或隧道过程。
  • RouteEvent:通过事件处理程序为触发的事件提供RoutedEvent对象。如果同一个事件处理程序处理不同的事件,这一信息是非常有用的。

自定义路由事件

三个步骤:

(1)   声明并注册路由事件。

(2)为路由事件添加CLR事件包装

(3)创建可以激发路由事件的方法

     public abstract class ButtonBase:ContentControl
    {
      //声明并注册路由事件
public static readonly RoutedEvent ClickEvent = EventManager.RegisterRoutedEvent("Click", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(ButtonBase));       //为路由事件添加CLR事件包装 public event RoutedEventHandler Click { add { this.AddHandler(ClickEvent, value); } remove { this.RemoveHandler(ClickEvent, value); } }
      //激发路由事件的方法,此方法用户在单击鼠标时会被Windows系统调用
protected virtual void OnClick() { RoutedEventArgs newEvent = new RoutedEventArgs(ButtonBase.ClickEvent, this); this.RaiseEvent(newEvent); } }
EventManager.RegisterRoutedEvent的四个参数
1)第一个参数string类型,被称为路由事件的名称,与CLR属性包装器的名称一致。
2)第二个参数为路由事件的策略,路由事件一般使用以下三种路由策略:
  • Bubble冒泡:由事件源向上传递一直到最外层容器(Window或者Page)。
  • Direct直达式:模仿CLR直接事件,直接将事件消息送达到事件处理器。
  • Tunnel隧道:从元素树的根部调用事件处理程序并依次向下深入直到事件源。

一般情况下,WPF提供的输入事件都是以隧道/冒泡对实现的。隧道事件常常被称为Preview事件。

3)第三个参数用于指定事件处理器的类型。事件处理器的返回值类型和参数列表必须与此参数指定的委托一致。

4)第四个参数用于指定路由事件的宿主是哪个类型。

 

posted @ 2021-08-29 16:12  HelloWorld庄先生  阅读(146)  评论(0)    收藏  举报