La maggior parte degli eventi esposti dai controlli Silverlight 2 sono i tipici eventi .NET, alcuni però sono eventi particolari chiamati Routed Event e sono:
Routed Event | |||
---|---|---|---|
KeyDown |
KeyUp |
GotFocus |
LostFocus |
MouseLeftButtonDown |
MouseLeftButtonUp |
MouseMove |
BindingValidationError |
La caratteristica di questo tipo di evento, chiamato anche Bubbling Event, è che non viene notificato solo sul controllo che lo scatena, ma viene propagato lungo tutto l'Object Tree, risalendo in sequenza gli oggetti padre, ammettendo quindi gestori multipli.
Per comprendere meglio questa caratteristica procediamo con una demo, in una pagina Silverlight inseriamo un controllo StackPanel
con un elemento figlio, un semplice Rectangle
. Infine per entrambi i controlli definiamo un handler per l'evento MouseLeftButtonDown
.
<StackPanel x:Name="LayoutRoot" Width="300" Background="Blue" MouseLeftButtonDown="LayoutRoot_MouseLeftButtonDown"> <Rectangle Fill="Black" Height="50" Width="100" Margin="10" MouseLeftButtonDown="Rectangle_MouseLeftButtonDown" /> </StackPanel>
Nei metodi generati nel code-behind invochiamo il metodo WriteLine
della classe Debug
passando come parametro il nome dell'hanlder, il quale sarà stampato nella console di output del debugger di Visual Studio.
private void LayoutRoot_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { Debug.WriteLine("-------------------------------------------------"); Debug.WriteLine("LayoutRoot_MouseLeftButtonDown"); } private void Rectangle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { Debug.WriteLine("-------------------------------------------------"); Debug.WriteLine("Rectangle_MouseLeftButtonDown"); }
Lanciamo l'applicazione e clicchiamo sul rettangolo nero, il risultato nella console di output saranno presenti entrambi i messaggi.
Questo particolare comportamento è molto utile nei casi in cui vogliamo creare un unico gestore degli eventi del mouse o della tastiera, scenario tipico di un videogame.
Dato che il parametro sender
rappresenta sempre il controllo dell'attuale gestore del Routed Event, per capire qual è stato il primo elemento dell'interfaccia utente a scatenare l'evento dobbiamo consultare la proprietà OriginalSource del parametro EventArgs
.
private void LayoutRoot_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { Debug.WriteLine("-------------------------------------------------"); Debug.WriteLine("LayoutRoot_MouseLeftButtonDown"); Debug.WriteLine("sender: " + sender); Debug.WriteLine("OriginalSource: " + e.OriginalSource); } private void Rectangle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { Debug.WriteLine("-------------------------------------------------"); Debug.WriteLine("Rectangle_MouseLeftButtonDown"); Debug.WriteLine("sender: " + sender); Debug.WriteLine("OriginalSource: " + e.OriginalSource); }
Mentre per interrompere l'attraversamento dei controlli basta impostare la proprietà handled
del parametro EventArgs
a true
.
private void Rectangle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { Debug.WriteLine("-------------------------------------------------"); Debug.WriteLine("Rectangle_MouseLeftButtonDown"); e.Handled = true; }