我在 WPF 中遇到了一些意想不到的行为。这是我的场景:
- 我在窗口上有一个用户控件。我们称之为“表面”。它上面有一个画布。
- 我有第二个用户控件。我们称之为“扑克牌”。
- 我将 PlayingCard UserControl 添加为 Surface 画布的子项。从视觉上看,它在 Surface 顶部显示应有的效果。
这都是一个窗口中“表面”之间的一些拖放操作的设置。我首先将 Surface 类上的所有拖放事件单独连接起来,一切正常。我可以正确检测到鼠标下的 PlayingCard UserControl 并拖动它,使用 Adorner 进行反馈等。
然后我将拖放内容抽象为一个单独的静态类。突然,鼠标点击下检测到的UIElement不再是PlayingCard,而是Surface!
我目前有三个不同的事件处理程序连接到 Surface 的 PreviewLeftMouseButtonDown 事件,另外我正在覆盖 Surface 上的 OnPreviewLeftMouseButtonDown 方法。我希望所有这些方法之间的行为一致来处理这种方法,但我没有得到它。结果如下:
(1) 我有一个名为 Test 的实例化类,它上面有一个连接到 Surface 的 PreviewLeftMouseButtonDown 事件的方法。这发生在 Window 的 main 方法中。它将 Surface 而不是 PlayingCard 检测为 Source。
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 事件。它将 Surface 检测为源:
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 的唯一事件处理程序是通过 XML 分配给 Surface 的事件处理程序。
为什么我会得到两个不同的结果?为什么其他事件处理程序不能正确地将 PlayingCard 报告为源?