我有一个像这样的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;。
怎么可能? 两次点击都应该返回相同的内容。
我没有使用任何自定义代码来处理鼠标。
答案 0 :(得分:0)
首先让我澄清一些事情,然后再讨论您遇到的实际行为。
MouseDown和MouseUp是耦合事件,即它们协同工作。 引发第一个mouseDown按钮,然后引发MouseUp事件。
此外,PreviewMouseUp和MouseUp之间存在差异。 PreviewMouseUp是隧道事件 ,它从根到事件的发起者,而 MouseUp是冒泡事件 它的根源。
您遇到的行为是正确的。当您点击dataGridColumnHeader时,让我们逐步了解示例:
在OriginalSource设置为TextBlock的情况下引发PreviewMouseDown事件,TextBlock从窗口传输到TextBlock。
然后引发MouseDown事件,该事件将从TextBlock传递到Window,除非它由之间的某个UIElement处理(即通过将e.Handled设置为true)。并且 DataGridColumnHeader会处理事件以排序列。 因此,它不会前往窗口。
现在,将引发相应的 PreviewMouseUp事件,其原始源将设置为处理MouseDown事件的控件 ,在您的情况下是DataGridColumnHeader。因此,您在控制台中看到DataGridColumnHeader。
您会看到,右键单击OriginalSource为TextBlock,因为DataGridColumnHeader不会处理 右键单击以对列进行排序。因此,它从根窗口到创建者TextBlock一起完美地传播。
同样适用于在Click事件中处理鼠标左键事件的Button。
因此,如果不使用PreviewMouseRightButtonUp和PreviewMouseLeftButtonUp, 使用PreviewMouseRightButtonDown和PreviewMouseLeftButtonDown,您将看到两种情况下的原始源相同 ,这将是TextBlock,因为MouseDown处理事件而不是PreviewMouseDown。
<DataGrid
PreviewMouseRightButtonDown="BookGrid_PreviewMouseRightButtonUp"
PreviewMouseLeftButtonDown="BookGrid_PreviewMouseRightButtonUp">....</DataGrid>
我建议您详细了解这些事件here。