WPF: Выделение элемента ListBoxItem и сброс выделения при повторном нажатии
Когда режим выделения элементов списка в XAML SelectionMode="Multiple", элемент выделяется по нажатию «мышью», и таким же образом сбрасывается выделение. В режиме Single выделение сбрасывается только при переключении на другой элемент или при удерживании клавиши Ctrl. Но что если нужно нечто среднее: выделение и снятие выделения элемента ListBoxItem по нажатию кнопкой «мыши», но выделение возможно только одного элемента?
Предлагаю такой вариант решения: задать списку ListBox или ListView множественный режим выделения и запрещать выделение более чем одного элемента. Сделаем это так (код на VB.NET):
''' <summary>'
''' Запрещает выделение множества элементов ListViewItem, когда режим выделения – Multiple.'
''' </summary>'
''' <remarks>Реализует поведение снятия выделения по второму клику на элементе, чтобы не нужно было удерживать Ctrl для снятия выделения.</remarks>'
Private Sub forbidSelectionButOne(sender As Object, e As MouseButtonEventArgs)
Dim lv As ListView = TryCast(sender, ListView)
If lv IsNot Nothing Then
If lv.SelectedIndex <> getCausesListViewItemIndex(sender, e) Then
lv.SelectedIndex = getCausesListViewItemIndex(sender, e)
e.Handled = True
End If
lv.Focus()
End If
End Sub
''' <summary>' ''' Возвращает индекс элемента списка, который был нажат мышью.' ''' </summary>' Private Function getCausesListViewItemIndex(ByVal sender As Object, e As RoutedEventArgs) As Integer Dim dep As DependencyObject = TryCast(e.OriginalSource, DependencyObject) Do While dep IsNot Nothing AndAlso Not TypeOf (dep) Is ListViewItem dep = VisualTreeHelper.GetParent(dep) Loop If dep Is Nothing Then Return -1 Else Dim lv As ListView = TryCast(sender, ListView) If lv IsNot Nothing Then Dim i As Integer = lv.ItemContainerGenerator.IndexFromContainer(dep) Return i Else Return -1 End If End If End Function
