15 Stimmen

Wie kann man verhindern, dass InvokeCommandAction das Ereignis an übergeordnete Elemente weitergibt?

Ich habe festgestellt, dass bei der Verwendung einer InvokeCommandAcction, die mit einem EventTrigger verbunden ist, das ursprüngliche Ereignis immer noch bis zu den übergeordneten Elementen weitergeleitet wird, bis es verarbeitet wird. Nun, ich denke, es ist ein erwartetes Verhalten. Aber meine Frage ist, wie ich das Ereignis als behandelt markieren kann, so dass es nicht durch den gesamten UI-Baum nach oben propagieren?

Da Sie dieses Ereignis in einem Befehl behandeln, wird alles in diesem Befehl behandelt, daher muss es nicht weitergegeben werden. Und in einer Ecke Fall fand ich, es verursacht einige unerwünschte Verhalten. Ich öffne zum Beispiel ein neues Fenster, wenn ein Benutzer auf ein Element doppelklickt (MouseDoubleClick-Ereignis). Das Problem ist, dass das neue Fenster geöffnet wird und dann das Hauptfenster wieder vor dem neuen Fenster erscheint, weil das MouseDoubleClick-Ereignis gerade das oberste Element im UI-Baum erreicht hat. Das gewünschte Verhalten wäre, das neue Fenster im Vordergrund zu halten, aber da die InvokeCommandAction das Ereignis nach oben propagieren lässt, nimmt das Hauptfenster den Fokus zurück...

Was ich tun könnte, ist das CallMethodAction-Asset stattdessen zu verwenden, aber wie ich in einem MVVM-Szenario bin, möchte ich nicht UI-Ereignis Argumente in meinem Code. Auch wenn dies mich implizit das Ereignis als behandelt markieren und das Problem beheben lassen würde.

<UserControl x:Class="..."
             xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="MouseDoubleClick">
            <i:InvokeCommandAction Command="{Binding Path=DisplayReportCommand}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
    ...
</UserControl>

24voto

Jens Punkte 24565

Sie könnten Ihren eigenen EventTrigger implementieren, der Ereignisse als behandelt markiert.

public class HandlingEventTrigger : System.Windows.Interactivity.EventTrigger
{
    protected override void OnEvent(System.EventArgs eventArgs)
    {
        var routedEventArgs = eventArgs as RoutedEventArgs;
        if (routedEventArgs != null)
            routedEventArgs.Handled = true;

        base.OnEvent(eventArgs);
    }
}

Dann ersetzen Sie <i:EventTrigger EventName="MouseDoubleClick"> con <local:HandlingEventTrigger EventName="MouseDoubleClick"> und hinzufügen

xmlns:local="clr-namespace:HandlingEventTrigger's namespace here"

zu den Attributen Ihres Benutzerkontrolls.

1voto

Wajeed-MSFT Punkte 2913

Angehängtes Ereignis zur Benutzersteuerung hinzufügen

              CommandManager.PreviewCanExecute="PreviewCanExecute" 

und im Ereignis-Handler

               e.ContinueRouting = false;

Ich hoffe, dies wird Hilfe !

0voto

Jin-Wook Chung Punkte 4104

MouseDoubleClick-Ereignis ist eigentlich kein blubberndes geroutetes Ereignis, sondern ein direktes geroutetes Ereignis.

Dieses Ereignis wird jedoch entlang des Elementbaums ausgelöst, was mit Snoop Werkzeug. Auch wenn Handled for MouseDoubleClick auf true gesetzt ist, wird dieses Ereignis entlang des Elementbaums auftreten.

Obwohl dieses geroutete Ereignis (MouseDoubleClick Event) scheinbar einen blubbernden Weg durch einen Elementbaum nimmt, handelt es sich in Wirklichkeit um ein direktes geroutetes Ereignis, das entlang des Elementbaums von jedem UIElement ausgelöst wird.

Wenn Sie die Handled-Eigenschaft in einem MouseDoubleClick-Ereignishandler auf true setzen, werden nachfolgende MouseDoubleClick-Ereignisse entlang der Route mit Handled auf false gesetzt. Dies ist ein übergeordnetes Ereignis für Benutzer von Steuerelementen, die benachrichtigt werden möchten, wenn der Benutzer auf das Steuerelement doppelt klickt, und die das Ereignis in einer Anwendung behandeln möchten. (Von MSDN )

Wie oben erwähnt, kann Ihr Problem nicht durch die von Ihnen erwähnte Ausbreitung verursacht werden. Es gibt die Eigenschaft Window.ShowActivated, die bestimmt, ob ein Fenster beim ersten Anzeigen aktiviert wird. Sie können die Eigenschaft in einem Unterfenster (xaml) wie unten festgelegt, aber bitte beachten Sie, dass obwohl ShowActivated kann den Fokus auf das Hauptfenster zu geben, kann es nicht lassen das Hauptfenster visuell vor dem Unterfenster zu halten. Ich habe versucht, die Lösung zu finden, habe aber bis jetzt keine Idee.

<Window ShowActivated="False" ....>
....
</Window>

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X