2011-01-12 17 views
6

Mi problema es que me gustaría manejar comandos en varios lugares. Por ejemplo, tengo mi UserControl personalizado, donde un botón está vinculado a algún comando. Tengo un comando vinculante en ese control pero también tengo un enlace de comando en una ventana que usa este control.RoutedCommands Ejecutados y eventos PreviewExecuted

Mi objetivo es realizar algunas acciones dentro del control sin interrumpir el manejo del comando en la ventana.

Intenté experimentar con los eventos Ejecutados y PreviewExecuted pero sin suerte. Luego simulé el problema en una sola ventana (código publicado a continuación).

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

Cuando pulso el botón sólo "CommandBindingWindow_PreviewExecuted" se imprimirá de forma. ¿Porqué es eso? Traté de configurar e.Handled en falso, pero no hace la diferencia. ¿Alguien puede explicar este comportamiento?

Respuesta

9

no tengo idea de por qué sucede esto (y cómo no es un error) pero aquí es lo que estaba escrito en el WPF wiki:

Hay una particularidad sobre CommandBinding que es muy interesante y importante saber.

El Administrador de comandos utiliza eventos enrutados para notificar a los diferentes objetos que CommandBinding ejecución de un comando era invocado (a través de gestos predeterminados, enlaces de entrada, de forma explícita, etc.).

Hasta ahora, esto es bastante sencillo. Sin embargo, lo que es más importante es que CommandBinding marcará el evento enrutado desde el CommandManager como manejado tan pronto como se ejecute un controlador ( PreviewExecuted o Executed).

Por último, incluso si el controlador tiene un prototipo que coincide con un delegado llamada ExecutedRoutedEventHandler, la evento Ejecutado de la CommandBinding no es un RoutedEvent sino un evento normal de CLR . Establecer o dejar e.Handled flag en false cambiará nada.

Por lo tanto, tan pronto como ejecutados o manejador PreviewExecuted se invoca, la RoutedCommand detengan su enrutamiento.

+1

¿Hay alguna manera de forzar al 'RoutedCommand' a continuar el enrutamiento? –

+0

@Matthew: Bueno ... Siempre puedes intentar volver a plantear el evento desde el método Ejecutado. – VitalyB

+0

el enlace al wiki de WPF está muerto. ¿Eso se movió a alguna parte? – dtm

Cuestiones relacionadas