Прослушиватели PreviewLeftMouseButtonDown сообщают о другом MouseButtonEventArgs.Source для того же события

У меня неожиданное поведение в WPF. Вот мой сценарий:

  1. У меня есть UserControl в окне. Назовем его «Поверхность». На нем есть холст.
  2. У меня есть второй UserControl. Назовем это «PlayingCard».
  3. У меня есть элемент управления PlayingCard UserControl, добавленный как дочерний элемент холста поверхности. Визуально он отображается так, как должен, поверх Surface.

Это все настройки для некоторых операций перетаскивания между «поверхностями» в окне. Я начал с индивидуального подключения всех событий перетаскивания в классе Surface, и все работало нормально. Я мог правильно обнаружить элемент управления PlayingCard UserControl под мышью и перетащить его, использовать Adorners для обратной связи и т. Д.

Затем я выделил внутренности перетаскивания в отдельный статический класс. Внезапно UIElement, обнаруженный при щелчке мышью, больше не является PlayingCard, а Surface!

В настоящее время у меня есть ТРИ разных обработчика событий, подключенных к событию Surface PreviewLeftMouseButtonDown, плюс я переопределяю метод OnPreviewLeftMouseButtonDown на Surface. Я ожидал бы согласованного поведения между всеми этими способами обработки этого метода, но я этого не понимаю. Вот результаты:

(1) У меня есть экземпляр класса Test, в котором есть метод, подключенный к событию PreviewLeftMouseButtonDown на поверхности. Это происходит в основном методе окна. Он определяет поверхность, а не воспроизводящуюся карту в качестве источника.

public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

           TestClass test = new TestClass();
           _leftSurface.PreviewMouseLeftButtonDown += test.Test_PreviewMouseLeftButtonDown;

(2) У меня есть статический класс DragDropManager, который также подключен к событию Surface, также в основном методе Window. Он также определяет в качестве источника Surface, а не PlayingCard.

public Window1()
        {
            InitializeComponent();

           TestClass test = new TestClass();
           _leftSurface.PreviewMouseLeftButtonDown += test.Test_PreviewMouseLeftButtonDown;

            _leftSurface.PreviewMouseMove += DragDropManager.PreviewMouseMove;

(3) Я переопределяю событие Surface OnPreviewLeftMouseButtonDown. Он определяет поверхность как источник:

  protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            base.OnPreviewMouseLeftButtonDown(e);

(4) У класса Surface есть собственный обработчик событий, указанный в XML, и он ПРАВИЛЬНО определяет PlayingCard в качестве источника.

<UserControl x:Class="WpfTest.Surface"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="300" Width="300">
    <Border Name="_border" BorderThickness="4" BorderBrush="Blue">
        <Canvas Name="_surface" Background="Black" AllowDrop="True"
                ClipToBounds="True"
                PreviewMouseMove="Surface_PreviewMouseMove"
                PreviewMouseLeftButtonDown="Surface_PreviewMouseLeftButtonDown"
                DragOver="Canvas_DragOver" DragLeave="Canvas_DragLeave">


        </Canvas>
    </Border>
</UserControl>

Единственный обработчик событий, который правильно определяет PlayingCard как MouseButtonEventArgs.Source, - это обработчик событий, который назначается Surface через XML.

Почему я получаю два разных результата? Почему другие обработчики событий неправильно указывают на PlayingCard как на источник?


person Chris Holmes    schedule 18.03.2009    source источник


Ответы (1)


Попробуйте e.OriginalSource.

person Donnelle    schedule 19.03.2009
comment
Я должен отвечать коротко, иначе моя рабочая сеть мгновенно отключится. - person Donnelle; 19.03.2009
comment
OriginalSource дает мне холст на поверхности. Нет помощи. - person Chris Holmes; 19.03.2009