WPF - Routed Events

EIN routed eventist eine Art von Ereignis, das Handler für mehrere Listener in einem Elementbaum aufrufen kann und nicht nur für das Objekt, das das Ereignis ausgelöst hat. Grundsätzlich handelt es sich um ein CLR-Ereignis, das von einer Instanz der Routed Event-Klasse unterstützt wird. Es ist beim WPF-Ereignissystem registriert. RoutedEvents haben drei Hauptroutingstrategien:

  • Direktes Ereignis
  • Sprudelndes Ereignis
  • Tunnelereignis

Direktes Ereignis

Ein direktes Ereignis ähnelt Ereignissen in Windows-Formularen, die von dem Element ausgelöst werden, von dem das Ereignis stammt.

Im Gegensatz zu einem Standard-CLR-Ereignis unterstützen direkt geroutete Ereignisse die Klassenbehandlung und können in Ereignissetzern und Ereignisauslösern in Ihrem Stil Ihres benutzerdefinierten Steuerelements verwendet werden.

Ein gutes Beispiel für ein direktes Ereignis wäre das MouseEnter-Ereignis.

Sprudelndes Ereignis

Ein sprudelndes Ereignis beginnt mit dem Element, aus dem das Ereignis stammt. Dann wandert es den visuellen Baum hinauf zum obersten Element im visuellen Baum. In WPF ist das oberste Element also höchstwahrscheinlich ein Fenster.

Tunnelereignis

Ereignishandler im Stammbaum des Elementbaums werden aufgerufen, und dann wandert das Ereignis über den visuellen Baum zu allen untergeordneten Knoten, bis es das Element erreicht, von dem das Ereignis stammt.

Der Unterschied zwischen einem Bubbling- und einem Tunneling-Ereignis besteht darin, dass ein Tunneling-Ereignis immer mit einer Vorschau beginnt.

In einer WPF-Anwendung werden Ereignisse häufig als Tunneling / Bubbling-Paar implementiert. Sie haben also eine Vorschau von MouseDown und dann ein MouseDown-Ereignis.

Im Folgenden finden Sie ein einfaches Beispiel für ein geroutetes Ereignis, bei dem eine Schaltfläche und drei Textblöcke mit einigen Eigenschaften und Ereignissen erstellt werden.

<Window x:Class = "WPFRoutedEvents.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "450" Width = "604" ButtonBase.Click  = "Window_Click" >
	
   <Grid> 
      <StackPanel Margin = "20" ButtonBase.Click = "StackPanel_Click">
		
         <StackPanel Margin = "10"> 
            <TextBlock Name = "txt1" FontSize = "18" Margin = "5" Text = "This is a TextBlock 1" /> 
            <TextBlock Name = "txt2" FontSize = "18" Margin = "5" Text = "This is a TextBlock 2" /> 
            <TextBlock Name = "txt3" FontSize = "18" Margin = "5" Text = "This is a TextBlock 3" /> 
         </StackPanel> 
			
         <Button Margin = "10" Content = "Click me" Click = "Button_Click" Width = "80"/> 
      </StackPanel> 
   </Grid> 
	
</Window>

Hier ist der C # -Code für die Implementierung von Click-Ereignissen für Button, StackPanel und Window.

using System.Windows; 
 
namespace WPFRoutedEvents { 
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary>
	
   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"; 
      }
		
   } 
}

Wenn Sie den obigen Code kompilieren und ausführen, wird das folgende Fenster angezeigt:

Wenn Sie auf die Schaltfläche klicken, werden die Textblöcke wie unten gezeigt aktualisiert.

Wenn Sie das geroutete Ereignis auf einer bestimmten Ebene stoppen möchten, müssen Sie e.Handled = true setzen.

Lassen Sie uns das ändern StackPanel_Click Ereignis wie unten gezeigt -

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

Wenn Sie auf die Schaltfläche klicken, werden Sie feststellen , dass das Click - Ereignis wird an das Fenster nicht weitergeleitet werden und wird auf der Stackpanel und die 3 stoppen rd Textblock nicht aktualisiert werden.

Benutzerdefinierte geroutete Ereignisse

In .NET Framework kann auch ein benutzerdefiniertes geroutetes Ereignis definiert werden. Sie müssen die folgenden Schritte ausführen, um ein benutzerdefiniertes geroutetes Ereignis in C # zu definieren.

  • Deklarieren und registrieren Sie Ihr geroutetes Ereignis mit dem Systemaufruf RegisterRoutedEvent.

  • Geben Sie die Routing-Strategie an, z. B. Blase, Tunnel oder Direkt.

  • Stellen Sie den Ereignishandler bereit.

Nehmen wir ein Beispiel, um mehr über benutzerdefinierte geroutete Ereignisse zu erfahren. Befolgen Sie die unten angegebenen Schritte -

  • Erstellen Sie ein neues WPF-Projekt mit WPFCustomRoutedEvent

  • Klicken Sie mit der rechten Maustaste auf Ihre Lösung und wählen Sie Hinzufügen> Neues Element ...

  • Der folgende Dialog wird geöffnet. Wählen Sie nun Custom Control (WPF) und nenne es MyCustomControl.

  • Drücke den Add Klicken Sie auf die Schaltfläche, und Sie werden sehen, dass zwei neue Dateien (Themes / Generic.xaml und MyCustomControl.cs) zu Ihrer Lösung hinzugefügt werden.

Der folgende XAML-Code legt den Stil für das benutzerdefinierte Steuerelement in der Datei Generic.xaml fest.

<ResourceDictionary 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:local = "clr-namespace:WPFCustomRoutedEvent">
	
   <Style TargetType = "{x:Type local:MyCustomControl}"> 
      <Setter Property = "Margin" Value = "50"/> 
      <Setter Property = "Template"> 
         <Setter.Value> 
            <ControlTemplate TargetType = "{x:Type local:MyCustomControl}">
				
               <Border Background = "{TemplateBinding Background}" 
                  BorderBrush = "{TemplateBinding BorderBrush}" 
                  BorderThickness = "{TemplateBinding BorderThickness}"> 
                  <Button x:Name = "PART_Button" Content = "Click Me" /> 
               </Border> 
					
            </ControlTemplate> 
         </Setter.Value> 
      </Setter> 
   </Style> 
	
</ResourceDictionary>

Unten ist der C # -Code für das angegeben MyCustomControl class das erbt von der Control class in dem ein benutzerdefiniertes geroutetes Ereignis Click für das benutzerdefinierte Steuerelement erstellt wird.

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); 
      }
		
   } 
}

Hier ist die benutzerdefinierte Implementierung eines gerouteten Ereignisses in C #, die ein Meldungsfeld anzeigt, wenn der Benutzer darauf klickt.

using System.Windows;  

namespace WPFCustomRoutedEvent { 
   // <summary> 
      // Interaction logic for MainWindow.xaml
   // </summary> 
	
   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"); 
      } 
		
   } 
}

Hier ist die Implementierung in MainWindow.xaml, um das benutzerdefinierte Steuerelement mit einem gerouteten Ereignis hinzuzufügen. Klicken Sie auf.

<Window x:Class = "WPFCustomRoutedEvent.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:local = "clr-namespace:WPFCustomRoutedEvent"
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
      <local:MyCustomControl Click = "MyCustomControl_Click" /> 
   </Grid> 
	
</Window>

Wenn der obige Code kompiliert und ausgeführt wird, wird das folgende Fenster erstellt, das ein benutzerdefiniertes Steuerelement enthält.

Wenn Sie auf das benutzerdefinierte Steuerelement klicken, wird die folgende Meldung angezeigt.