Пользовательское действие WF4: почему e.Handled = true в DoubleClick не прекращает пузыриться
Привет Я использую пользовательскую активность 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();
}
}
}
3 ответа
MSDN имеет ответ для вас: ссылка
Цитата: хотя это перенаправленное событие (Control.MouseDoubleClick Event
), кажется, следует по пузырчатому маршруту через дерево элементов, на самом деле это событие прямой маршрутизации, которое вызывается вдоль дерева элементов каждым элементом UIElement. Если для свойства Handled установлено значение true в обработчике события MouseDoubleClick, последующие события MouseDoubleClick вдоль маршрута будут происходить, а для параметра Handled установлено значение false. Это событие более высокого уровня для потребителей элементов управления, которые хотят получать уведомления, когда пользователь дважды щелкает элемент управления и обрабатывает событие в приложении.
Замечание в Макусе ссылка продолжается так:
Авторы элементов управления, которые хотят обрабатывать двойные щелчки мыши, должны использовать событие MouseLeftButtonDown, когда ClickCount равен двум. Это приведет к соответствующему распространению состояния 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;
}
}
}
Вы пытались использовать статическое bool для обработанного свойства? Я помню ту же проблему с перетаскиванием и решил ее таким образом.