简体   繁体   English

自定义WF4活动:为什么DoubleClick中的e.Handled = true不会停止冒泡

[英]Custom WF4 Activity: Why e.Handled = true in DoubleClick don't stops bubbling

Hallo I'm using custom WF4 activity which can be nested by self. 您好,我正在使用自定义WF4活动,该活动可以自己嵌套。 I have to catch a double-click event, so I rewrote OnPreviewMouseDoubleClick method. 我必须捕获一个双击事件,因此我重写了OnPreviewMouseDoubleClick方法。 My problem is that when activity is inside the other activity and am the double click to inner one, the double click is invoked on both of them. 我的问题是,当一个活动在另一个活动中并且是对内部活动的双击时,在两个活动上都调用了双击。 I set the e.Handled = true but it doesn't work. 我将e.Handled设置为true,但是它不起作用。 How can I stop to execute the double click event on parent activities. 如何停止对父级活动执行双击事件。

Here is my example of codes: 这是我的代码示例:

ActivityDesigner1.xaml ActivityDesigner1.xaml

<sap:ActivityDesigner x:Class="ActivityDesignerLibrary1.ActivityDesigner1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:sap="clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation"
    xmlns:sapv="clr-namespace:System.Activities.Presentation.View;assembly=System.Activities.Presentation">
    <Grid>
        <sap:WorkflowItemsPresenter Items="{Binding Path=ModelItem.Activities}">
            <sap:WorkflowItemsPresenter.SpacerTemplate>
                <DataTemplate>
                    <Label HorizontalAlignment="Center" Content="Drop activity here." FontStyle="Italic" Foreground="DarkGray" />
                </DataTemplate>
            </sap:WorkflowItemsPresenter.SpacerTemplate>
        </sap:WorkflowItemsPresenter>
    </Grid>
</sap:ActivityDesigner>

ActivityDesigner1.xaml.cs ActivityDesigner1.xaml.cs

using System.Windows;
using System.Windows.Input;

namespace ActivityDesignerLibrary1
{
    public partial class ActivityDesigner1
    {
        public ActivityDesigner1()
        {
            InitializeComponent();
        }

        protected override void OnPreviewMouseDoubleClick(MouseButtonEventArgs e)
        {
            e.Handled = true;
            base.OnPreviewMouseDoubleClick(e);
            MessageBox.Show(this.GetHashCode().ToString());   
        }
    }
}

CodeActivity1.cs CodeActivity1.cs

using System;
using System.Activities;
using System.Activities.Statements;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace ActivityDesignerLibrary1
{
    [Designer(typeof(ActivityDesigner1))]
    public sealed class CodeActivity1 : CodeActivity
    {
        private Sequence innerSequence = new Sequence();

        public Collection<Activity> Activities
        {
            get
            {
                return this.innerSequence.Activities;
            }
        }

        protected override void Execute(CodeActivityContext context)
        {
            throw new NotImplementedException();
        }
    }
}

Remark in Makus link continues like this: Makus链接中的备注继续如下:

Control authors who want to handle mouse double clicks should use the MouseLeftButtonDown event when ClickCount is equal to two. 当ClickCount等于2时,想要处理鼠标双击的控件作者应使用MouseLeftButtonDown事件。 This will cause the state of Handled to propagate appropriately in the case where another element in the element tree handles the event. 在元素树中的另一个元素处理事件的情况下,这将导致Handled状态适当传播。

So I created this workaround: 因此,我创建了此解决方法:

using System.Windows;
using System.Windows.Input;
using System.Activities.Presentation;
using System.Windows.Media;

namespace ActivityDesignerLibrary1
{
    public partial class ActivityDesigner1
    {
        public ActivityDesigner1()
        {
            InitializeComponent();
        }

        protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
        {
            if (e.ClickCount == 2)
            {
                FrameworkElement fe = e.OriginalSource as FrameworkElement;
                if (fe != null)
                {
                    object original = fe.DataContext;
                    ActivityDesigner baseActivityDesigner = original as ActivityDesigner;
                    if (baseActivityDesigner == null)
                    {
                        baseActivityDesigner = this.ActivityDesignerFinder((DependencyObject)e.OriginalSource);
                    }

                    if (baseActivityDesigner != null)
                    {
                        MessageBox.Show(baseActivityDesigner.GetHashCode().ToString());
                        e.Handled = true;
                    }
                }
            }
        }


        private ActivityDesigner ActivityDesignerFinder(DependencyObject dependencyObject)
        {
            while (dependencyObject != null)
            {
                if (dependencyObject is ActivityDesigner)
                {
                    return (ActivityDesigner)dependencyObject;
                }

                dependencyObject = VisualTreeHelper.GetParent(dependencyObject);
            }

            return null;
        }
    }
}

Have you tried using a static bool for the handled property? 您是否尝试过对处理的属性使用静态布尔? I remember having a same issue with drag&drop and solved it this way. 我记得拖放存在相同的问题,并以此方式解决了该问题。

MSDN has answer for you: link MSDN为您解答: 链接

Quote: Although this routed event ( Control.MouseDoubleClick Event ) seems to follow a bubbling route through an element tree, it actually is a direct routed event that is raised along the element tree by each UIElement. Quote:尽管此路由事件( Control.MouseDoubleClick Event )似乎遵循通过元素树的冒泡路由,但实际上它是每个UIElement沿元素树引发的直接路由事件。 If you set the Handled property to true in a MouseDoubleClick event handler, subsequent MouseDoubleClick events along the route will occur with Handled set to false. 如果在MouseDoubleClick事件处理程序中将Handled属性设置为true,则沿路由的后续MouseDoubleClick事件将在Handled设置为false的情况下发生。 This is a higher-level event for control consumers who want to be notified when the user double-clicks the control and to handle the event in an application. 对于控件使用者,这是一个较高级别的事件,它们希望在用户双击控件时得到通知并在应用程序中处理该事件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM