📜  WPF-路由事件

📅  最后修改于: 2020-11-18 09:52:21             🧑  作者: Mango


路由事件是一种事件,可以在元素树中的多个侦听器上调用处理程序,而不仅仅是引发该事件的对象。基本上,这是CLR事件,由Routed Event类的实例支持。它已在WPF事件系统中注册。 RoutedEvents具有三种主要的路由策略,如下所示:

  • 直接事件
  • 冒泡事件
  • 隧道事件

直接事件

直接事件类似于Windows表单中的事件,这些事件是由事件发生的元素引发的。

与标准CLR事件不同,直接路由事件支持类处理,并且可以在自定义控件样式的事件设置器和事件触发器中使用它们。

直接事件的一个很好的例子是MouseEnter事件。

冒泡事件

冒泡事件始于事件发生的元素。然后,它沿着视觉树向上移动到视觉树中的最顶层元素。因此,在WPF中,最上面的元素很可能是一个窗口。

隧道事件

调用元素树根上的事件处理程序,然后事件沿视觉树向下传播到所有子节点,直到到达事件发生的元素为止。

冒泡事件与隧道事件之间的区别在于,隧道事件将始终以预览开始。

在WPF应用程序中,事件通常实现为隧道/冒泡对。因此,您将有一个预览MouseDown,然后是MouseDown事件。

下面给出的是路由事件的简单示例,其中创建了一个按钮和三个带有某些属性和事件的文本块。


    
    
      
        
          
             
             
             
          
            
          
       
    
    

这是Button,StackPanel和Window的Click事件实现的C#代码。

using System.Windows; 
 
namespace WPFRoutedEvents { 
   ///  
      /// Interaction logic for MainWindow.xaml 
   /// 
    
   public partial class MainWindow : Window { 
    
      public MainWindow() { 
         InitializeComponent(); 
      }  
        
      private void Button_Click(object sender, RoutedEventArgs e) { 
         txt1.Text = "Button is Clicked"; 
      } 
        
      private void StackPanel_Click(object sender, RoutedEventArgs e) { 
         txt2.Text = "Click event is bubbled to Stack Panel"; 
      } 
        
      private void Window_Click(object sender, RoutedEventArgs e) { 
         txt3.Text = "Click event is bubbled to Window"; 
      }
        
   } 
}

当您编译并执行上述代码时,它将产生以下窗口-

路由事件

当您单击按钮时,文本块将得到更新,如下所示。

点击按钮

如果要在任何特定级别停止路由事件,则需要设置e.Handled = true;。

让我们更改StackPanel_Click事件,如下所示-

private void StackPanel_Click(object sender, RoutedEventArgs e) { 
   txt2.Text = "Click event is bubbled to Stack Panel"; 
   e.Handled = true; 
}

当你点击按钮,你会发现,点击事件不会被路由到窗口,将在StackPanel的停止和第三文本块将不会被更新。

点击事件

自定义路由事件

在.NET Framework中,还可以定义自定义路由事件。您需要按照下面给出的步骤在C#中定义自定义路由事件。

  • 使用系统调用RegisterRoutedEvent声明并注册您的路由事件。

  • 指定路由策略,即冒泡,隧道或直接。

  • 提供事件处理程序。

让我们以一个示例来了解有关自定义路由事件的更多信息。请按照下面给出的步骤-

  • 使用WPFCustomRoutedEvent创建一个新的WPF项目

  • 右键单击您的解决方案,然后选择添加>新建项目…

  • 将打开以下对话框,现在选择“自定义控件(WPF)”并将其命名为MyCustomControl

自定义路由事件

  • 单击添加按钮,您将看到在解决方案中将添加两个新文件(Themes / Generic.xaml和MyCustomControl.cs)。

以下XAML代码为Generic.xaml文件中的自定义控件设置样式。


    
    
    

下面给出的是MyCustomControl类的C#代码,该类继承自Control类,在Control类中为自定义控件创建了自定义路由事件Click。

using System.Windows; 
using System.Windows.Controls;  

namespace WPFCustomRoutedEvent { 

   public class MyCustomControl : Control { 
    
      static MyCustomControl() { 
         DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomControl), 
            new FrameworkPropertyMetadata(typeof(MyCustomControl))); 
      } 
        
      public override void OnApplyTemplate() { 
         base.OnApplyTemplate();
            
         //demo purpose only, check for previous instances and remove the handler first 
         var button  =  GetTemplateChild("PART_Button") as Button; 
         if (button ! =  null) 
         button.Click + =  Button_Click;  
      } 
        
      void Button_Click(object sender, RoutedEventArgs e) { 
         RaiseClickEvent(); 
      } 
        
      public static readonly RoutedEvent ClickEvent  =  
         EventManager.RegisterRoutedEvent("Click", RoutingStrategy.Bubble, 
         typeof(RoutedEventHandler), typeof(MyCustomControl)); 
            
      public event RoutedEventHandler Click { 
         add { AddHandler(ClickEvent, value); } 
         remove { RemoveHandler(ClickEvent, value); } 
      } 
        
      protected virtual void RaiseClickEvent() { 
         RoutedEventArgs args = new RoutedEventArgs(MyCustomControl.ClickEvent); 
         RaiseEvent(args); 
      }
        
   } 
}

这是C#中的自定义路由事件实现,当用户单击它时将显示一个消息框。

using System.Windows;  

namespace WPFCustomRoutedEvent { 
   //  
      // Interaction logic for MainWindow.xaml
   //  
    
   public partial class MainWindow : Window { 
    
      public MainWindow() { 
         InitializeComponent(); 
      }  
        
      private void MyCustomControl_Click(object sender, RoutedEventArgs e) { 
         MessageBox.Show("It is the custom routed event of your custom control"); 
      } 
        
   } 
}

这是MainWindow.xaml中的实现,用于添加具有路由事件Click的自定义控件。

 
    
    
       
    
    

编译并执行上述代码后,将产生以下窗口,其中包含一个自定义控件。

自定义控件

当您单击自定义控件时,它将产生以下消息。

单击自定义control.jpg