将ListBox选择更改为切换选择的最佳方法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将ListBox选择更改为切换选择的最佳方法相关的知识,希望对你有一定的参考价值。
我有一个ListBox控件,我想改为切换选择。即,单击一个项目选择它,再次单击它取消选择它。此外,单击列表中的其他项应执行取消选择上一项并选择新项的默认操作。
实现这一目标的最佳方法是什么?
你想要的是一个RadioButtonList。您可以通过创建ItemDataTemplate并在其中放置RadioButton来创建一个。然后,您可以将RadioButton的模板修改为看起来像一个按钮。
我会保持标准的ListBox,你将保持你想要的默认行为,然后取消选择一个项目你可以在鼠标按下事件中处理它吗?即使用这样的东西:
Point newPoint = e.GetPosition(backgroundImage);
HitTestResult result = VisualTreeHelper.HitTest(this, newPoint);
if (result.VisualHit is ListBoxItem)
我不确定这是否是最好的方法,我要做的唯一其他方法是从标准的Windows控件派生我自己的ListBox并添加依赖属性以允许我处理样式中的取消选择。如果你想采用这种方法,我不应该删除你想要保留的默认行为,我使用这种方法创建一个ListBox,它将在文本旁边显示一个图像。
如果您需要任何指示从哪里开始,那么请给我一个喊叫。
我通过稍微创建两个自定义类ToggleListBox和ToggleListBoxItem来实现这一目标。有几个方便的覆盖(ToggleListBox中最重要的是创建ListBoxItem的覆盖)。
从那里很容易处理两次点击相同的项目,或按空格/输入键。两个类的40行代码,工作正常。
万一有人感兴趣,我找到了一个不同的解决方案,这对我很有用。我将ListBox.SelectionMode
设置为Multiple
并因此处理了MouseDown事件:
EventManager.RegisterClassHandler(typeof(ListBoxItem),
ListBoxItem.MouseLeftButtonDownEvent,
new RoutedEventHandler(this.HandleListBox_MouseDown));
...
void HandleListBox_MouseDown(object sender, RoutedEventArgs e)
{
var listBoxItem = (ListBoxItem)sender;
if (ShouldDeselectOtherListItems(listBoxItem))
{
listBox.SelectedIndex = -1;
}
}
bool ShouldDeselectOtherListItems(ListBoxItem listBoxItem)
{
return !listBoxItem.IsSelected
&& listBox.SelectedItems.Count > 0;
}
其中listBox是父ListBox控件。它确保在处理系统MouseDown事件处理程序之前取消选择所有列表框项目,从而允许切换相同的列表框项目的选择状态。
我开始寻找一种“内置”的方式来做到这一点。当我看到没有,并注意到我不喜欢的答案时,我想我会发布我认为最好的方法。
这个答案与Bijington的答案最相似我只是在ListBox中添加了一个PreviewMouseDown处理程序
<ListBox ... PreviewMouseLeftButtonDown="ListBox_OnPreviewMouseLeftButtonDown"... />
然后在代码中
private void ListBox_OnPreviewMouseLeftButtonDown (object sender, MouseButtonEventArgs e)
{
// I have a special extension for GetParent, numerous examples on the internet of how you would do that
var lbi = ((DependencyObject) e.OriginalSource).GetParent<ListBoxItem>();
if (lbi != null && lbi.IsSelected)
{
lbi.IsSelected = false;
e.Handled = true;
}
}
然后我认为将它变成附加属性会很好,这很容易就像这样......
public static class ListBoxEx
{
private static DependencyProperty ToggleSelectionProperty = ...
private static bool GetToggleSelection (ListBox obj) { ... }
private static void SetToggleSelection (ListBox obj, bool shouldToggle)
{
obj.SetValue(ToggleSelectionProperty, shouldToggle);
if (shouldToggle)
{
obj.PreviewMouseLeftButtonDown += ToggleListBox_OnPreviewMouseLeftButtonDown ;
}
else
{
obj.PreviewMouseLeftButtonDown -= ToggleListBox_OnPreviewMouseLeftButtonDown ;
}
}
private static void ToggleListBox_OnPreviewMouseLeftButtonDown (object sender, MouseButtonEventArgs e)
{
// I have a special extension for GetParent, numerous examples on the internet of how you would do that
var lbi = ((DependencyObject) e.OriginalSource).GetParent<ListBoxItem>();
if (lbi != null && lbi.IsSelected)
{
lbi.IsSelected = false;
e.Handled = true;
}
}
}
然后在代码中:
<ListBox ... yourNamespace:ListBoxEx.ToggleSelection="True" />
相关信息:
- 附属物帮助:Microsoft Documentation Link
- GetParent实用程序示例:MSDN Link
以上是关于将ListBox选择更改为切换选择的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章