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