WPF自定义路由事件

发布时间 2023-12-06 10:33:02作者: ZHIZRL

声明与封装

创建一个继承ContentControl的类,因为封装需要使用AddHandler和RemoveHandler

RegisterRoutedEvent的参数RoutingStrategy传入RoutingStrategy.Bubble为冒泡事件,传入RoutingStrategy.Tunnel为隧道事件

申明公开的event RoutedEventHandler封装RoutedEvent

/// 用于路由事件 
    /// 
    /// </summary>
    /// 
    public class BaseClass : ContentControl
    {
        // 路由事件的声明与注册
        // (冒泡事件)
        protected static readonly RoutedEvent TapEvent =    
            EventManager.RegisterRoutedEvent(
                "Tap",
                RoutingStrategy.Bubble,
                typeof(RoutedEventHandler),
                typeof(BaseClass));

        public event RoutedEventHandler Tap
        {
            add => AddHandler(TapEvent, value);
            remove => RemoveHandler(TapEvent, value);
        }

        /// <summary>
        /// 隧道事件 
        /// </summary>
        /// 
        protected static readonly RoutedEvent PreviewTapEvent =
            EventManager.RegisterRoutedEvent(
                "PreviewTap",
                RoutingStrategy.Tunnel,
                typeof(RoutedEventHandler),
                typeof(BaseClass));

        public event RoutedEventHandler PreviewTap
        {
            add => AddHandler(PreviewTapEvent, value);
            remove => RemoveHandler(PreviewTapEvent, value);
        }
    }

 自定义路由的使用

创建两个自定义控件,并继承BaseClass

在ChildClass控件初始化两秒后触发路由事件

    public class ParentClass : BaseClass
    { }

    public class ChildClass : BaseClass
    {
        public ChildClass()
        {
            // 场景,类里数据执行到某个时机的时候  ,触发上面的路由事件
            Task.Run(async () =>
            {
                await Task.Delay(2000);

                // 触发路由事件
                this.Dispatcher.Invoke(() =>
                {
                    // 先Parent  后Child
                    this.RaiseEvent(new RoutedEventArgs(PreviewTapEvent, this));

                    // 先Child  后Parent
                    this.RaiseEvent(new RoutedEventArgs(TapEvent, this));
                });
            });
        }
    }
    <Grid local:BaseClass.Tap="Grid_Tap" local:BaseClass.PreviewTap="Grid_PreviewTap">
        <local:ParentClass Tap="ParentClass_Tap" PreviewTap="ParentClass_PreviewTap">
            <local:ChildClass Tap="ChildClass_Tap" PreviewTap="ChildClass_PreviewTap"/>
        </local:ParentClass>
    </Grid>
    /// <summary>
    /// CustomEventWindow.xaml 的交互逻辑
    /// </summary>
    public partial class CustomEventWindow : Window
    {

        public CustomEventWindow()
        {
            InitializeComponent();
        }
        private void ParentClass_Tap(object sender, RoutedEventArgs e)
        {
            Debug.WriteLine("============ParentClass_Tap============");
        }
        private void ChildClass_Tap(object sender, RoutedEventArgs e)
        {
            Debug.WriteLine("============ChildClass_Tap============");
        }

        private void ParentClass_PreviewTap(object sender, RoutedEventArgs e)
        {
            Debug.WriteLine("============ParentClass_PreviewTap============");
        }

        private void ChildClass_PreviewTap(object sender, RoutedEventArgs e)
        {
            Debug.WriteLine("============ChildClass_PreviewTaps============");
        }

        private void Grid_Tap(object sender, RoutedEventArgs e)
        {
            Debug.WriteLine("============Grid_Tap============");
        }

        private void Grid_PreviewTap(object sender, RoutedEventArgs e)
        {
            Debug.WriteLine("============Grid_PreviewTap============");
        }
    }

运行后在输出窗口中打印结果如下

============Grid_PreviewTap============
============ParentClass_PreviewTap============
============ChildClass_PreviewTaps============
============ChildClass_Tap============
============ParentClass_Tap============
============Grid_Tap============