繁体   English   中英

WPF - 在自定义控件上处理自定义附加事件

[英]WPF - Handling custom attached events on custom controls

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

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子类,则行为将恢复为已损坏的无事件似乎处于获取状态。

这对我来说并不是很有意义。 为了让这个场景有效,我需要做些什么吗? 看起来应该没关系。 我想有可能在我的所有自定义控件中都有一个特定的事情会导致事件处理中断,但我在目前为止尝试的三个或四个自定义控件中没有看到任何常见的东西。

你没有发布所有代码,所以我不得不推断并整理我自己的版本。 它适用于我。 也许比较和对比你的代码:

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>

暂无
暂无

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

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