Я получаю неожиданное поведение в WPF. Вот мой сценарий:
- У меня есть UserControl в окне. Давайте назовем это «Поверхность». На нем есть холст.
- У меня есть второй UserControl. Давайте назовем это «PlayingCard».
- У меня есть пользовательский элемент управления 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?