我有一个ListBox控件,我想更改为具有切换选择。即,单击一个项目选择它,再次单击它取消选择它。此外,单击列表中的其他项应执行取消选择上一项并选择新项的默认操作。
实现这一目标的最佳方式是什么?
答案 0 :(得分:2)
你想要的是RadioButtonList。您可以通过创建ItemDataTemplate并在其中放置RadioButton来创建一个。然后,您可以将RadioButton的模板修改为看起来像一个按钮。
答案 1 :(得分:0)
我会保持标准的ListBox,你将保持你想要的默认行为,然后取消选择一个项目你可以在鼠标按下事件中处理它吗?即使用这样的东西:
Point newPoint = e.GetPosition(backgroundImage);
HitTestResult result = VisualTreeHelper.HitTest(this, newPoint);
if (result.VisualHit is ListBoxItem)
我不确定这是否是最好的方法,我要做的唯一其他方法是从标准的Windows控件派生我自己的ListBox并添加一个依赖属性以允许我处理取消选择风格。如果你想采用这种方法,我不应该删除你想要保留的默认行为,我使用这种方法创建一个ListBox,它将在文本旁边显示一个图像。
如果你需要任何关于从哪里开始的指示,那就给我一个大喊。
答案 2 :(得分:0)
我已经设法通过稍微创建两个自定义类来实现这一目标,ToggleListBox& ToggleListBoxItem。有几个方便的覆盖(ToggleListBox中最重要的是创建ListBoxItem的那个)。
从那里可以轻松地点击同一项目两次,或者按空格键/输入键。两个类的40行代码都可以正常工作。
答案 3 :(得分:0)
万一有人对此感兴趣,我找到了一个不同的解决方案,这对我很有用。我将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事件处理程序之前取消选择所有列表框项目,从而允许切换相同的列表框项目的选择状态。
答案 4 :(得分:0)
我着手寻找一种“内置”方式来做到这一点。当我看到没有答案时,发现这里不是我真正想要的答案,我想我会发布我认为最好的答案。
此答案与Bijington的答案最相似 我只是向列表框添加了一个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