2011-01-12 11 views
6

Il mio problema è che mi piacerebbe gestire un comando in più posti. Ad esempio, ho il mio UserControl personalizzato in cui un pulsante è associato a un comando. Ho un binding di comando in quel controllo ma ho anche un binding di comando in una Window che usa questo controllo.RoutedCommands Executed and PreviewExecuted events

Il mio obiettivo è eseguire un'azione all'interno del controllo senza interrompere la gestione del comando nella finestra.

Ho provato a sperimentare eventi Eseguiti e Anteprima eseguiti ma senza fortuna. Quindi ho simulato il problema in una singola finestra (codice pubblicato di seguito).

<Window x:Class="CommandingEvents.Window1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:CommandingEvents="clr-namespace:CommandingEvents" 
    Title="Window1" Height="300" Width="300"> 
<Window.CommandBindings> 
    <CommandBinding 
     Command="{x:Static CommandingEvents:Window1.Connect}" 
     Executed="CommandBindingWindow_Executed" 
     PreviewExecuted="CommandBindingWindow_PreviewExecuted"/> 
</Window.CommandBindings> 
<Grid> 
    <Grid.CommandBindings> 
     <CommandBinding 
     Command="{x:Static CommandingEvents:Window1.Connect}" 
     Executed="CommandBindingGrid_Executed" 
     PreviewExecuted="CommandBindingGrid_PreviewExecuted" /> 
    </Grid.CommandBindings> 
    <Button Command="{x:Static CommandingEvents:Window1.Connect}" 
      CommandTarget="{Binding RelativeSource={RelativeSource Self}}" 
      Content="Test" HorizontalAlignment="Center" VerticalAlignment="Center" /> 
</Grid> 

namespace CommandingEvents 
{ 
    public partial class Window1 
    { 
     public static readonly RoutedUICommand Connect = new 
      RoutedUICommand("Connect", "Connect", typeof(Window1)); 

     public Window1() 
     { 
      InitializeComponent(); 
     } 

     private void CommandBindingWindow_Executed(object sender, ExecutedRoutedEventArgs e) 
     { 
      Console.WriteLine("CommandBindingWindow_Executed"); 
      e.Handled = false; 
     } 

     private void CommandBindingGrid_Executed(object sender, ExecutedRoutedEventArgs e) 
     { 
      Console.WriteLine("CommandBindingGrid_Executed"); 
      e.Handled = false; 
     } 

     private void CommandBindingWindow_PreviewExecuted(object sender, ExecutedRoutedEventArgs e) 
     { 
      Console.WriteLine("CommandBindingWindow_PreviewExecuted"); 
      e.Handled = false; 
     } 

     private void CommandBindingGrid_PreviewExecuted(object sender, ExecutedRoutedEventArgs e) 
     { 
      Console.WriteLine("CommandBindingGrid_PreviewExecuted"); 
      e.Handled = false; 
     } 
    } 
} 

Quando mi ha colpito il pulsante unico "CommandBindingWindow_PreviewExecuted" viene stampato. Perché? Ho provato a impostare e.Handled su false ma non fa differenza. Qualcuno può spiegare questo comportamento?

risposta

9

Non ho idea del perché ciò accade (e come non è un bug), ma qui è quello che è stato scritto nel WPF wiki:

C'è una particolarità su CommandBinding che è estremamente interessante e importante sapere

Il CommandManager utilizza eventi indirizzati notificare i diversi CommandBinding oggetti che esecuzione di un comando era invocato (attraverso gesti predefiniti, associazioni di input, in modo esplicito, ecc).

Fino ad ora, questo è abbastanza semplice. Tuttavia, è importante che sia importante che CommandBinding contenga l'evento indirizzato dal comando come gestito non appena viene eseguito un gestore (sia Anteprima eseguita o eseguita).

Infine, anche se il gestore ha un prototipo che corrisponde un delegato chiamato ExecutedRoutedEventHandler, il dell'evento eseguito dal CommandBinding non è un RoutedEvent, ma un normale evento CLR . Impostando o lasciando e.Handled flag su false cambierà nulla.

Pertanto, non appena un realizzati o gestore PreviewExecuted viene invocato, il RoutedCommand fermerà la sua routing.

+1

C'è un modo per forzare il 'RoutedCommand' per continuare il routing? –

+0

@Matthew: Beh, puoi sempre provare a controrilanciare l'evento dal metodo Executed. – VitalyB

+0

il collegamento al wiki WPF è morto. è spostato da qualche parte? – dtm