2011-01-12 9 views
6

Mein Problem ist, dass ich eine Befehle an mehreren Orten behandeln möchte. Zum Beispiel habe ich mein benutzerdefiniertes Benutzersteuerelement, wo eine Schaltfläche an einen Befehl gebunden ist. Ich habe einen Befehl, der in diesem Steuerelement bindet, aber ich habe auch einen Befehl, der in einem Fenster bindet, das dieses Steuerelement verwendet.RoutedCommands Executed und PreviewExecuted Ereignisse

Mein Ziel ist es, eine Aktion innerhalb des Steuerelements auszuführen, während die Behandlung des Befehls im Fenster nicht unterbrochen wird.

Ich habe versucht, mit Executed und PreviewExecuted-Events zu experimentieren, aber ohne Glück. Dann habe ich das Problem in einem einzigen Fenster simuliert (Code unten).

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

Wenn ich den Knopf drücken nur "CommandBindingWindow_PreviewExecuted" ausgedruckt. Warum das? Ich habe versucht, e.Handled auf false zu setzen, aber es macht keinen Unterschied. Kann jemand dieses Verhalten erklären?

Antwort

9

Ich habe keine Ahnung, warum das passiert (und wie es ist kein Fehler), aber hier ist das, was in der WPF wiki geschrieben wurde:

Es ist eine Besonderheit über Command die extrem interessant und Wichtig zu wissen.

Der Befehlsmanager verwendet gerouteten Ereignisse die verschiedenen Command Objekte zu benachrichtigen, dass eine Befehlsausführung war aufgerufen (durch Standard Gestik, Eingabebindungen, explizit, etc.).

Bis jetzt ist dies ziemlich unkompliziert. Wichtiger ist jedoch, dass CommandBinding das geroutete Ereignis vom CommandManager als behandelt behandelt, sobald ein Handler ausgeführt wird (entweder PreviewExecuted oder Executed).

Schließlich, auch wenn der Handler einen Prototyp hat, die einen Delegierten Spiele ExecutedRoutedEventHandler, die Ausgeführt Ereignis aus der Command genannt ist kein RoutedEvent aber ein normaler CLR Ereignis. Wenn Sie das Flag " e.Handled" auf "false" setzen oder belassen, wird nichts geändert.

Daher sobald ein aufgerufen Ausgeführt oder PreviewExecuted Handler, die RoutedCommand seine Routing stoppen.

+1

Gibt es eine Möglichkeit, den 'RoutedCommand' zu zwingen, weiter zu routen? –

+0

@Matthew: Nun .. Sie könnten immer versuchen, das Ereignis von der Executed-Methode erneut zu erhöhen. – VitalyB

+0

Der Link zu WPF Wiki ist tot. Hat sich das irgendwo bewegt? – dtm