WPF - Eventi indirizzati

UN routed eventè un tipo di evento che può invocare gestori su più listener in una struttura ad albero piuttosto che solo l'oggetto che ha generato l'evento. È fondamentalmente un evento CLR supportato da un'istanza della classe Routed Event. È registrato con il sistema di eventi WPF. RoutedEvents ha tre principali strategie di routing che sono le seguenti:

  • Evento diretto
  • Evento di ribollimento
  • Evento Tunnel

Evento diretto

Un evento diretto è simile agli eventi nei Windows Form che vengono generati dall'elemento da cui ha origine l'evento.

A differenza di un evento CLR standard, gli eventi indirizzati direttamente supportano la gestione delle classi e possono essere utilizzati nei setter di eventi e nei trigger di eventi all'interno del tuo stile di controllo personalizzato.

Un buon esempio di un evento diretto sarebbe l'evento MouseEnter.

Evento di ribollimento

Un evento di bubbling inizia con l'elemento da cui ha avuto origine l'evento. Quindi viaggia lungo l'albero visivo fino all'elemento più in alto nell'albero visivo. Quindi, in WPF, l'elemento più in alto è molto probabilmente una finestra.

Evento Tunnel

I gestori di eventi nella radice dell'albero degli elementi vengono richiamati e quindi l'evento viaggia lungo l'albero visivo verso tutti i nodi figli fino a raggiungere l'elemento in cui ha avuto origine l'evento.

La differenza tra un evento di bubbling e un evento di tunneling è che un evento di tunneling inizierà sempre con un'anteprima.

In un'applicazione WPF, gli eventi vengono spesso implementati come una coppia di tunneling / bubbling. Quindi, avrai un'anteprima MouseDown e quindi un evento MouseDown.

Di seguito è riportato un semplice esempio di un evento indirizzato in cui vengono creati un pulsante e tre blocchi di testo con alcune proprietà ed eventi.

<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>

Di seguito è riportato il codice C # per l'implementazione degli eventi Click per Button, StackPanel e 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"; 
      }
		
   } 
}

Quando compili ed esegui il codice sopra, produrrà la seguente finestra:

Quando fai clic sul pulsante, i blocchi di testo verranno aggiornati, come mostrato di seguito.

Se si desidera arrestare l'evento indirizzato a un livello particolare, sarà necessario impostare e.Handled = true;

Cambiamo il file StackPanel_Click evento come mostrato di seguito -

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

Quando si fa clic sul pulsante, si osserverà che l'evento del clic non verrà indirizzato alla finestra e si fermerà allo stackpanel e il 3 ° blocco di testo non verrà aggiornato.

Eventi indirizzati personalizzati

In .NET framework, è possibile definire anche eventi indirizzati personalizzati. È necessario seguire i passaggi indicati di seguito per definire un evento indirizzato personalizzato in C #.

  • Dichiara e registra il tuo evento indirizzato con la chiamata di sistema RegisterRoutedEvent.

  • Specificare la strategia di instradamento, ad esempio Bubble, Tunnel o Diretto.

  • Fornisci il gestore eventi.

Facciamo un esempio per capire di più sugli eventi indirizzati personalizzati. Segui i passaggi indicati di seguito:

  • Crea un nuovo progetto WPF con WPFCustomRoutedEvent

  • Fare clic con il tasto destro sulla soluzione e selezionare Aggiungi> Nuovo elemento ...

  • Si aprirà la seguente finestra di dialogo, ora seleziona Custom Control (WPF) e nominalo MyCustomControl.

  • Clicca il Add e vedrai che due nuovi file (Themes / Generic.xaml e MyCustomControl.cs) verranno aggiunti alla tua soluzione.

Il codice XAML seguente imposta lo stile per il controllo personalizzato nel file Generic.xaml.

<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>

Di seguito è riportato il codice C # per MyCustomControl class che eredita dal Control class in cui viene creato un evento indirizzato personalizzato Click per il controllo personalizzato.

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

Ecco l'implementazione dell'evento indirizzato personalizzato in C # che visualizzerà una finestra di messaggio quando l'utente fa clic su di essa.

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

Ecco l'implementazione in MainWindow.xaml per aggiungere il controllo personalizzato con un evento indirizzato Click.

<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>

Quando il codice precedente viene compilato ed eseguito, produrrà la seguente finestra che contiene un controllo personalizzato.

Quando si fa clic sul controllo personalizzato, verrà visualizzato il seguente messaggio.