【问题标题】:Custom WF4 Activity: Why e.Handled = true in DoubleClick don't stops bubbling自定义 WF4 活动:为什么 DoubleClick 中的 e.Handled = true 不会停止冒泡
【发布时间】:2012-12-17 08:30:26
【问题描述】:

您好,我正在使用可以自行嵌套的自定义 WF4 活动。我要捕捉双击事件,所以我重写了 OnPreviewMouseDoubleClick 方法。我的问题是,当活动在另一个活动中并且双击到内部活动时,对它们都调用了双击。我设置了 e.Handled = true 但它不起作用。如何停止在父活动上执行双击事件。

这是我的代码示例:

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

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

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

【问题讨论】:

  • 删除 base.OnPreviewMouseDoubleClick(e); 并重试。
  • 谢谢您,我刚刚删除了它,但仍然无法使用。

标签: c# xaml workflow-foundation-4 workflow-activity activitydesigner


【解决方案1】:

Makus 链接中的备注如下:

想要处理鼠标双击的控件作者应该在 ClickCount 等于 2 时使用 MouseLeftButtonDown 事件。这将导致 Handled 的状态在元素树中的另一个元素处理事件的情况下适当地传播。

所以我创建了这个解决方法:

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

【讨论】:

    【解决方案2】:

    MSDN 为您解答: link

    Quote: 尽管此路由事件 (Control.MouseDoubleClick Event) 似乎遵循通过元素树的冒泡路由,但它实际上是由每个 UIElement 沿元素树引发的直接路由事件。如果在 MouseDoubleClick 事件处理程序中将 Handled 属性设置为 true,则路由中的后续 MouseDoubleClick 事件将在 Handled 设置为 false 的情况下发生。对于希望在用户双击控件时收到通知并在应用程序中处理事件的控件使用者来说,这是一个更高级别的事件。

    【讨论】:

    • 谢谢你的链接很有帮助。
    【解决方案3】:

    您是否尝试过为所处理的属性使用静态布尔值? 我记得在拖放时遇到了同样的问题,并以这种方式解决了它。

    【讨论】:

    • 是的,将属性 e.Handled 设置为 true 在拖放中效果很好,但在双击时效果不佳。
    • 就像我说的:我在拖放时遇到了同样的问题,并通过使用静态属性修复了它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-11
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 2018-07-26
    • 2016-01-25
    • 2017-02-14
    相关资源
    最近更新 更多