左键单击返回不同的originSource而不是右键单击

时间:2014-07-05 14:52:43

标签: c# wpf xaml

我有一个像这样的DataGrid:

<DataGrid
PreviewMouseRightButtonUp="BookGrid_PreviewMouseRightButtonUp"             
PreviewMouseLeftButtonUp="BookGrid_PreviewMouseRightButtonUp">....</DataGrid>

(datagrid是带有自动生成列的默认数据网格)

代码背后:

   private void BookGrid_PreviewMouseRightButtonUp(object sender, MouseButtonEventArgs e)
   {
        Debug.WriteLine(e.OriginalSource);
   }

例如,当我用鼠标左键单击列标题时,调试打印出来:

System.Windows.Controls.Primitives.DataGridColumnHeader:Category

但是当我用右手鼠标点击同一地点时:

System.Windows.Controls.TextBlock

当我尝试单击表单按钮时,左键单击&#34; System.Windows.Controls.Button:Edit&#34;, 右键单击&#34; System.Windows.Controls.TextBlock&#34;。

怎么可能? 两次点击都应该返回相同的内容。

我没有使用任何自定义代码来处理鼠标。

1 个答案:

答案 0 :(得分:0)

首先让我澄清一些事情,然后再讨论您遇到的实际行为。

MouseDown和MouseUp是耦合事件,即它们协同工作。 引发第一个mouseDown按钮,然后引发MouseUp事件。


此外,PreviewMouseUp和MouseUp之间存在差异。 PreviewMouseUp是隧道事件 ,它从根到事件的发起者,而 MouseUp是冒泡事件 它的根源。


您遇到的行为是正确的。当您点击dataGridColumnHeader时,让我们逐步了解示例:

  1. 在OriginalSource设置为TextBlock的情况下引发PreviewMouseDown事件,TextBlock从窗口传输到TextBlock。

  2. 然后引发MouseDown事件,该事件将从TextBlock传递到Window,除非它由之间的某个UIElement处理(即通过将e.Handled设置为true)。并且 DataGridColumnHeader会处理事件以排序列。 因此,它不会前往窗口。

  3. 现在,将引发相应的 PreviewMouseUp事件,其原始源将设置为处理MouseDown事件的控件 ,在您的情况下是DataGridColumnHeader。因此,您在控制台中看到DataGridColumnHeader。

  4. 您会看到,右键单击OriginalSource为TextBlock,因为DataGridColumnHeader不会处理 右键单击以对列进行排序。因此,它从根窗口到创建者TextBlock一起完美地传播。

    同样适用于在Click事件中处理鼠标左键事件的Button。


    因此,如果不使用PreviewMouseRightButtonUp和PreviewMouseLeftButtonUp, 使用PreviewMouseRightButtonDown和PreviewMouseLeftButtonDown,您将看到两种情况下的原始源相同 ,这将是TextBlock,因为MouseDown处理事件而不是PreviewMouseDown。

    <DataGrid
    PreviewMouseRightButtonDown="BookGrid_PreviewMouseRightButtonUp"             
    PreviewMouseLeftButtonDown="BookGrid_PreviewMouseRightButtonUp">....</DataGrid>
    

    我建议您详细了解这些事件here