“MouseLeftButtonDown”事件在TreeViewItem中没有触发,为什么?

4

我在WPF应用程序中有一个 TreeView,如下所示。

<TreeView x:Name="documentOutlinePanel">
    <TreeView.ItemContainerStyle>
         <Style TargetType="{x:Type TreeViewItem}">
             <EventSetter Event="TreeViewItem.MouseLeftButtonDown" Handler="TreeViewItem_MouseLeftButtonDown"/>
           </Style>
     </TreeView.ItemContainerStyle>
</TreeView>

在代码后台文件中存在事件处理程序,以下是该处理程序的代码。
private void TreeViewItem_MouseLeftButtonDown(object sender,   MouseButtonEventArgs e)
{
    // some code.
}

我还在处理两个HierarchicalDataTemplate,用于TreeView控件中可能出现的项。
通过设置TreeViewItemsSource属性来绑定TreeView的项。
问题:
MouseLeftButtonDown的处理程序根本没有执行。
我在此方法的处理程序开头设置了一个断点,但断点根本没有被命中。
但是需要注意的是: PreviewMouseLeftButtonDown会触发,我可以处理它(我不关心这个事件)
有人能解释一下为什么MouseLeftButtonDown没有被触发吗? 有什么建议让它触发吗?
更新:此问题与 MouseLeftButtonDown is not fired on TreeViewItem 不重复
我看到了那个问题和它的答案,但它并不适合我。以下是区别:
1.那个问题是针对SilverLigth的,而我的是针对WPF的。 2.那个问题是处理TreeView.MouseLeftButtonDown,而我的是处理TreeViewItem.MouseLeftButtonDown。 3.我阅读了那个问题的答案,并没有帮助到我。

我看到了这个问题和它的答案,但并不适用于我。以下是区别:
  1. 那个问题是关于SliverLigth的,而我的是关于WPF的。
  2. 那个问题是处理TreeView.MouseLeftButtonDown事件,而我的是处理TreeViewItem.MouseLeftButtonDown事件。
  3. 我阅读了那个问题的答案,但对我没有帮助。
无论如何,谢谢。
- Hakan Fıstık
2个回答

4

谢谢@qqww2,你的回答可能很有用,虽然我没有尝试过,因为我找到了一个更漂亮的解决方案。
我阅读了TreeViewItem.OnMouseLeftButtonDown源代码,并发现如果TreeViewItem成功获取焦点,则该方法会将此事件标记为已处理。
所以我将TreeViewItem对象设置为UnFocusable

<TreeView x:Name="documentOutlinePanel">
    <TreeView.ItemContainerStyle>
      <Style TargetType="{x:Type TreeViewItem}">
          <Setter Property="Focusable" Value="False"/>
          <EventSetter Event="TreeViewItem.MouseLeftButtonDown" Handler="TreeViewItem_MouseLeftButtonDown"/>
      </Style>
   </TreeView.ItemContainerStyle>
</TreeView>

这会触发 MouseLeftButtonDown 事件。在此事件的处理程序中,我这样设置了它的 Focus
private void TreeViewItem_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    TreeViewItem item = (TreeViewItem)sender;
    // do what i want.

    item.Focusable = true;
    item.Focus();
    item.Focusable = false;
    e.Handled = true;
}
e.Handled被设置为true,因为我注意到这个事件会发生两次,一次是针对TreeViewItem,另一次是针对其父TreeViewItem。(因为这个事件是冒泡事件),所以最终总是选择父TreeViewItem
如果有人遇到相同的问题,这对我很有效。

3

实际上,您在那个问题中遇到了相同的问题。在TreeViewItem.OnMouseLeftButtonDown中,事件被标记为已处理,因此它不再冒泡。

您可以通过调用下面的代码并为TreeViewItem注册自己到MouseDownEvent来克服这个问题。但是请注意,此代码会重定向所有应用程序中的TreeViewItem的事件。这可能或可能不适合您。此外,此事件对于所有鼠标按钮都会触发,但您可以轻松检查单击的按钮是否为Left

EventManager.RegisterClassHandler(typeof(TreeViewItem), Mouse.MouseDownEvent, new MouseButtonEventHandler(OnMouseButtonDown), true);

2
实际上,您仍然可以连接到 MouseLeftButtonDown,因此您不必检查单击了哪个鼠标按钮:EventManager.RegisterClassHandler(typeof(TreeViewItem), TreeViewItem.MouseLeftButtonDownEvent, ... - Sphinxxx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接