PreviewLeftMouseButtonDown Слушатели сообщают о разных MouseButtonEventArgs.Source For Same Event - PullRequest
0 голосов
/ 19 марта 2009

Я получаю неожиданное поведение в WPF. Вот мой сценарий:

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

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

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

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

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

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

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

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

public Window1()
        {
            InitializeComponent();

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

            _leftSurface.PreviewMouseMove += DragDropManager.PreviewMouseMove;

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

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

(4) Класс Surface имеет свой собственный обработчик событий, указанный в XML, и он ПРАВИЛЬНО обнаруживает PlayCard в качестве источника.

<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.

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

1 Ответ

1 голос
/ 19 марта 2009

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

...