Я отправился на поиски «встроенного» способа сделать это. Когда я увидел, что их нет, и заметил здесь ответы, которые мне не очень понравились, я решил опубликовать то, что, по моему мнению, лучший способ сделать это.
Этот ответ наиболее похож на Bijington
Я просто добавил обработчик PreviewMouseDown в ListBox
<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" />
Соответствующая информация: