如何防止 InvokeCommandAction 将事件传播到父元素? [英] How to prevent InvokeCommandAction from propagating event to parent elements?

查看:25
本文介绍了如何防止 InvokeCommandAction 将事件传播到父元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我意识到当使用与 EventTrigger 关联的 InvokeCommandAcction 时,原始事件仍在路由到父元素,直到它被处理.好吧,我想这是一种预期的行为.但我的问题是如何将事件标记为已处理,以便它不会在整个 UI 树中向上传播?

I realised that when using an InvokeCommandAcction associated to an EventTrigger, the original event was still routing up to the parent elements until it is handled. Well, I guess it is an expected behavior. But my question is how I can mark the event as Handled so it does not propagate up through the whole UI tree?

实际上,当您在命令中处理此事件时,所有内容都将在此命令中处理,因此不需要传播.在我发现的一个极端情况下,它会导致一些不需要的行为.例如,当用户双击一个元素(MouseDoubleClick 事件)时,我会打开一个新窗口.问题是新窗口打开,然后主窗口回到新窗口的前面,因为 MouseDoubleClick 事件刚刚到达 UI 树中的顶部元素.想要的行为是将新窗口保持在前面,但是当 InvokeCommandAction 让事件向上传播时,主窗口收回焦点...

Actually, as you handle this event in a command, everything will be handled in this command, therefore it does not need to propagate. And in one corner case I found, it causes some unwanted behavior. For example, I open a new window when a user double click an element (MouseDoubleClick event). The problem is that the new windows opens and then the main window come back in front of the new one because the MouseDoubleClick event just reached the top element in the UI tree. The wanted behavior would be to keep the new window in front, but as the InvokeCommandAction lets the event propagate up, the main window takes back the focus...

我可以做的是改用 CallMethodAction 资产,但由于我处于 MVVM 场景中,我不想在我的代码中使用 UI 事件参数.即使这会让我隐式地将事件标记为已处理并解决问题.

What I could do is to use the CallMethodAction asset instead but as I am in a MVVM scenario, I don't want UI event arguments in my code. Even if this would let me implicitely mark the event as handled and fix the issue.

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

推荐答案

您可以实现自己的 EventTrigger,将事件标记为已处理.

You could implement your own EventTrigger that marks events as handled.

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

然后将 替换为 并添加

Then replace <i:EventTrigger EventName="MouseDoubleClick"> with <local:HandlingEventTrigger EventName="MouseDoubleClick"> and add

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

到您的用户控件的属性.

to your usercontrol's atributes.

这篇关于如何防止 InvokeCommandAction 将事件传播到父元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆