WPF MVVM模式下路由事件

一,路由事件下三种路由策略:

1 冒泡:由事件源向上传递一直到根元素。2直接:只有事件源才有机会响应事件。3隧道:从元素树的根部调用事件处理程序并依次向下深入直到事件源。一般情况下,WPF提供的输入事件都是以隧道/冒泡对实现的。隧道事件常常被称为Preview事件。

二,MVVM简单的路由注册事件

.CS

public class MainViewModel : ViewModelBase
    {
        public MainViewModel()
        {
      //这里使用了Preview事件 EventManager.RegisterClassHandler(typeof(Grid), Grid.PreviewMouseLeftButtonDownEvent, new RoutedEventHandler(OnClick)); } void OnClick(object sender, RoutedEventArgs e) { if (e.Source is Button) { MessageBox.Show($"{Grid.GetRow((e.Source as Button))}:{(e.Source as Button).Name}" ); } } }

.XAML

    <Grid >
        <Grid.RowDefinitions>
            <RowDefinition Height="50"></RowDefinition>
            <RowDefinition Height="50"></RowDefinition>
            <RowDefinition Height="50"></RowDefinition>
        </Grid.RowDefinitions>
        <Button x:Name="Grid1" Width="50"  HorizontalContentAlignment="Center" >1</Button>
        <Button Grid.Row="1" x:Name="Grid2" Width="50" >2</Button>
    </Grid>

效果

三,自定义路由事件 

1,创建一个BottonV类

     class BottonV:Button
    {

        //第一步:声明并注册【路由事件】        
        //EventManager.RegisterRoutedEvent(CLR事件包装器名称,路由事件冒泡策略,事件处理程序的类型,路由事件的所有者类类型)        
        public static readonly RoutedEvent OpenEvent = EventManager.RegisterRoutedEvent("Open", RoutingStrategy.Bubble, typeof(EventHandler<CustomRouting>), typeof(BottonV));
        //第二步:为路由事件添加CLR事件包装器    
        public event RoutedEventHandler Open
        {
            //为指定的路由事件添加路由事件处理程序,并将该处理程序添加到当前元素的处理程序集合中。
            add { this.AddHandler(OpenEvent, value); }
            remove { this.RemoveHandler(OpenEvent, value); }

        }
        //第三步:激发路由事件
        protected override void OnClick()
        {
            base.OnClick();
            //创建事件携带信息(RoutedEventArgs类实例),并和路由事件关联       
            CustomRouting args = new CustomRouting(OpenEvent, this);
            args.EventTime = DateTime.Now;
            //调用元素的RaiseEvent方法(继承自UIElement类),引发路由事件       
            this.RaiseEvent(args);
        }
    }

2,定义一个路由

 /// <summary>
    /// 继承RoutedEventArgs
    /// </summary>
    public class CustomRouting:RoutedEventArgs
    {
        public CustomRouting(RoutedEvent routedEvent, object source) : base(routedEvent, source) { }
        public DateTime EventTime { get; set; }

    }

3,MainWindow页面创建一个路由事件

  private void TimeButton_ReportTime(object sender, CustomRouting e)//注意参数
        {
            MessageBox.Show(e.EventTime.ToLongTimeString() + (sender as FrameworkElement).Name);
        }

效果如下:

原文地址:https://www.cnblogs.com/zt199510/p/13543766.html