WPF - обработка пользовательских вложенных событий на пользовательских элементах управления - PullRequest
7 голосов
/ 27 августа 2009

У меня перенаправлено событие как таковое (имена были изменены для защиты невинных):

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>

Это не дает желаемых результатов. В частности, хотя вызывается код, который вызывает RaiseEvent () для события DragComplete, обработчик никогда не вызывается. Фактически, это также не обработчики для любых других пользовательских перенаправленных событий, которые подключены где-либо еще в этом файле XAML.

Я попытался изменить имя перенаправленного события и попытался переключить шаблон данных с одного с типом данных на другой с ключом x :. Это не произвело видимых изменений в поведении.

Однако, если я изменю My: CustomControl на любой встроенный элемент управления WPF, например TextBlock, события будут выполняться точно так же, как и я. Точно так же, если я заменю свой пользовательский элемент управления на любой другой пользовательский подкласс UserControl из моего проекта, поведение вернется к нарушенному состоянию без событий, когда-либо кажущихся полученными.

Это не имеет большого смысла для меня. Есть ли что-то конкретное, что мне нужно сделать, чтобы этот сценарий заработал? Кажется, это не должно иметь значения. Я предполагаю, что, возможно, есть определенная вещь, которую я сделал во всех моих пользовательских элементах управления, которая вызывает прерывание обработки событий, но я не видел ничего общего в трех или четырех пользовательских элементах управления, которые я до сих пор пробовал.

1 Ответ

1 голос
/ 27 августа 2009

Вы не опубликовали весь свой код, поэтому мне пришлось сделать вывод и собрать свою собственную версию. Это работает хорошо для меня. Возможно, сравните и противопоставьте свой код:

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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...