如何防止ListBox在右键单击时选择项目?

8
这里有一个棘手的问题,每个项目都有一个ContextMenu,但我仍然希望在右键单击时打开它(只是不想选中它)。
实际上,如果这样做可以更容易些,我根本不想自动选择任何内容,所以如果有办法完全禁用它那就太好了。
我正在考虑切换到ItemsControl,只要我能让虚拟化和滚动正常工作。
1个回答

24

如果你完全不需要选择,我肯定会使用ItemsControl而不是ListBox。只要他们在模板中,虚拟化和滚动都可以与普通的ItemsControl一起使用。

另一方面,如果你需要选择但只是不想通过右键单击进行选择,则最简单的方法可能是处理PreviewRightMouseButtonDown事件:

void ListBox_PreviewRightMouseButtonDown(object sender, MouseButtonEventArgs e)
{
  e.Handled = true;
}
这种方法有效的原因是ListBoxItem的选择发生在鼠标按下时,但上下文菜单的打开发生在鼠标释放时。因此,在预览阶段消除鼠标按下事件可以解决您的问题。
然而,如果您希望在ListBox中的其他位置(如项内的控件)处理鼠标按下,则此方法无效。在这种情况下,最简单的方法可能是子类化ListBoxItem并将其忽略。
public class ListBoxItemNoRightClickSelect : ListBoxItem
{
  protected override void OnMouseRightButtonDown(MouseButtonEventArgs e)
  {
  }
}

你可以在 ItemsSource 中显式构建这些 ListBoxItems,也可以子类化 ListBox 来自动使用你的自定义项:

public class ListBoxNoRightClickSelect : ListBox
{
  protected override DependencyObject GetContainerForItemOverride()
  {
    return new ListBoxItemNoRightClickSelect();
  }
}

提供一些行不通的解决方案,以及为什么这些方案不可行:

  • 不能只在每个ListBoxItem上添加MouseRightButtonDown处理程序,因为已注册的类处理程序会在你的处理程序之前被调用
  • 无法在ListBox上处理MouseRightButtonDown,因为事件直接路由到每个控件个体身上

谢谢 - 我最终采用了ItemsControl的方法(实现方式如此https://dev59.com/DXE85IYBdhLWcg3wbS5h),现在不仅按照我的要求工作,而且性能也明显提高了! - devios1

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