如果你完全不需要选择,我肯定会使用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,因为事件直接路由到每个控件个体身上