Domanda

Il mio problema è che mi piacerebbe gestire un comandi in più posti. Per esempio io ho la mia UserControl personalizzato in cui un pulsante è associato a qualche comando. Ho un ordine vincolante in tale controllo, ma ho anche un comando vincolante in una finestra che utilizza questo controllo.

Il mio obiettivo è quello di eseguire alcune azioni all'interno del controllo pur non interrompendo la gestione del comando nella finestra.

Ho provato a sperimentare con eventi eseguito e PreviewExecuted ma senza fortuna. Poi ho simulato il problema in una singola finestra (codice pubblicato sotto).

<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 cercato di impostare e.Handled a false, ma non fa la differenza. Qualcuno può spiegare questo comportamento?

È stato utile?

Soluzione

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 da sapere.

     

Il CommandManager utilizza eventi indirizzati   a notificare alla diversa CommandBinding   oggetti che esecuzione di un comando era   invocata (attraverso gesti predefiniti,   associazioni di input, in modo esplicito, ecc.).

     

Fino ad oggi, questo è abbastanza   semplice. Tuttavia, ciò che è più   importante è che la volontà CommandBinding   celebrare l'evento indirizzato dal   CommandManager come gestito, non appena un   handler viene eseguito (sia   PreviewExecuted o Eseguito).

     

Infine, anche se il gestore ha un   prototipo che corrisponde a un delegato   chiamato ExecutedRoutedEventHandler, il   dell'evento eseguito dal CommandBinding   non è un RoutedEvent ma un CLR normale   evento. Impostazione o in uscita dalla   Bandiera e.Handled al cambiamento volontà falsa   nulla.

     

Quindi, non appena un Eseguito o   gestore PreviewExecuted viene richiamato,   il RoutedCommand fermerà la sua   instradamento.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top