7

我有一个这样声明的路由事件(名称已更改以保护无辜者):

public class DragHelper : DependencyObject {
    public static readonly RoutedEvent DragCompleteEvent = EventManager.RegisterRoutedEvent(
        "DragComplete",
        RoutingStrategy.Bubble,
        typeof(DragRoutedEventHandler),
        typeof(DragHelper)
    );

    public static void AddDragCompleteHandler( DependencyObject dependencyObject, DragRoutedEventHandler handler ) {
        UIElement element = dependencyObject as UIElement;
        if (element != null) {
            element.AddHandler(DragCompleteEvent, handler);
        }
    }

    public static void RemoveDragCompleteHandler( DependencyObject dependencyObject, DragRoutedEventHandler handler ) {
        UIElement element = dependencyObject as UIElement;
        if (element != null) {
            element.RemoveHandler(DragCompleteEvent, handler);
        }
    }

很标准的东西。在 XAML 中,我有一个包含单个自定义控件的 DataTemplate。我正在尝试将此事件(以及其他一些附加属性)附加到控件:

<DataTemplate ...>
    <My:CustomControl
        My:DragHelper.IsDragSource="True"
        My:DragHelper.DragComplete="DragCompleteHandler" />
</DataTemplate>

这无法产生预期的结果。具体来说,在调用为 DragComplete 事件调用 RaiseEvent() 的代码时,从不调用处理程序。事实上,在此 XAML 文件中的其他位置连接的任何其他自定义路由事件的处理程序也不是。

我尝试更改路由事件的名称,并尝试将数据模板从一个带有 DataType 的模板切换到一个带有 x:Key 的模板。这在行为上没有产生明显的变化。

但是,如果我将 My:CustomControl 更改为任何内置 WPF 控件(例如 TextBlock),则事件将完全按照我的预期触发。同样,如果我用我的项目中的任何其他自定义 UserControl 子类替换我的自定义控件,则行为将恢复为损坏的、无事件似乎无法处理的状态。

这对我来说没有多大意义。我需要做一些具体的事情来让这个场景起作用吗?好像应该没关系。我想有可能我在所有自定义控件中所做的特定事情会导致事件处理中断,但到目前为止我还没有看到我尝试过的三个或四个自定义控件中有任何共同点。

4

1 回答 1

1

你还没有发布你所有的代码,所以我不得不推断并组合我自己的版本。它对我来说没问题。也许与您的代码进行比较和对比:

Window1.xaml.cs

using System.Windows;
using System.Windows.Controls;

namespace WpfApplication1
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        private void DragCompleteHandler(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("YEP");
        }
    }

    public class CustomControl : TextBox
    {
    }

    public class DragHelper : DependencyObject
    {
        public static readonly DependencyProperty IsDragSourceProperty = DependencyProperty.RegisterAttached("IsDragSource",
            typeof(bool),
            typeof(DragHelper),
            new FrameworkPropertyMetadata(OnIsDragSourceChanged));

        public static bool GetIsDragSource(DependencyObject depO)
        {
            return (bool)depO.GetValue(IsDragSourceProperty);
        }

        public static void SetIsDragSource(DependencyObject depO, bool ids)
        {
            depO.SetValue(IsDragSourceProperty, ids);
        }

        public static readonly RoutedEvent DragCompleteEvent = EventManager.RegisterRoutedEvent(
            "DragComplete",
            RoutingStrategy.Bubble,
            typeof(RoutedEventHandler),
            typeof(DragHelper)
        );

        public static void AddDragCompleteHandler(DependencyObject dependencyObject, RoutedEventHandler handler)
        {
            UIElement element = dependencyObject as UIElement;
            if (element != null)
            {
                element.AddHandler(DragCompleteEvent, handler);
            }
        }

        public static void RemoveDragCompleteHandler(DependencyObject dependencyObject, RoutedEventHandler handler)
        {
            UIElement element = dependencyObject as UIElement;
            if (element != null)
            {
                element.RemoveHandler(DragCompleteEvent, handler);
            }
        }

        private static void OnIsDragSourceChanged(DependencyObject depO, DependencyPropertyChangedEventArgs e)
        {
            (depO as TextBox).TextChanged += delegate
            {
                (depO as TextBox).RaiseEvent(new RoutedEventArgs(DragCompleteEvent, null));
            };
        }
    }
}

Window1.xaml

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <DataTemplate x:Key="Test">
            <local:CustomControl
                local:DragHelper.IsDragSource="True"
                local:DragHelper.DragComplete="DragCompleteHandler" />
        </DataTemplate>
    </Window.Resources>

    <ContentControl ContentTemplate="{StaticResource Test}"/>
</Window>
于 2009-08-27T18:58:29.753 回答