2013-06-24 5 views
2

Мне нужно реализовать пользовательское поведение для элемента управления ListBox в wpf. Идея состоит в том, чтобы отключить отменить выбор последнего выбранного элемента. Согласно поведению по умолчанию, когда пользователь нажимает на выбранный элемент мышью, удерживая нажатой клавишу ctrl, выбор исчезает. Мне нужно реализовать некоторую логику, чтобы сделать listbox ничего не делать, когда пользователь нажимает кнопку мыши + ctrl на последний выбранный элемент.Лучший способ предотвратить удаление выбранного последнего элемента в ListBox

Единственный подход я нашел это подписаться на ListBox.SelectionChanged и сделать что-то вроде этого:

private static void listBox_SelectionChanged(object sender, SelectionChangedEventArgs e) 
     { 
      var listBox = sender as ListBox; 
      if (listBox != null && e.RemovedItems != null && e.RemovedItems.Count == 1) 
      { 
       var removed = e.RemovedItems[0]; 
       if (listBox.SelectedItems.Count == 0) 
       { 
        if (listBox.SelectionMode == System.Windows.Controls.SelectionMode.Single) 
        { 
         listBox.SelectedItem = removed; 
        } 
        else 
        { 
         listBox.SelectedItems.Add(removed); 
        } 

        e.Handled = true; 
       } 
      } 
     } 

, но это решение не подходит для меня, потому что в этом случае некоторые нежелательные звонки происходит, когда ListBox. SelectedItem привязан к свойству viewmodel.

псевдо CallStack (при отмене выбора выбранного элемента):

  1. SelectedItem изменено на нуль

  2. listBox_SelectionChanged называется

  3. SelectedItem устанавливается в предыдущее значение

Все, что я хочу, это тот шаг с 1 и 3 никогда не бывает. Это важно, потому что, когда SelectedItem изменяет, запускается некоторая длительная работа async.

Спасибо, любые советы будут оценены!

ответ

1

Найдено решение. Обработка PreviewMouseLeftButtonDown в ListBox отлично подходит для меня. Сделано в качестве прикрепленного имущества.

BTW: Могу ли я как-то закрыть вопрос?

public static class ListBoxAttachedProperties 
    { 
     public static readonly DependencyProperty DisableUnselectLast = 
      DependencyProperty.RegisterAttached(
      "DisableUnselectLast", typeof(bool), typeof(ListBox), 
      new PropertyMetadata(false, DisableUnselectLastChangedCallback)); 

     public static bool GetDisableUnselectLast(DependencyObject d) 
     { 
      return (bool)d.GetValue(DisableUnselectLast); 
     } 

     public static void SetDisableUnselectLast(DependencyObject d, bool value) 
     { 
      d.SetValue(DisableUnselectLast, value); 
     } 

     private static void DisableUnselectLastChangedCallback(
      DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      if (!(d is ListBox)) 
      { 
       return; 
      } 

      var selector = d as ListBox; 
      bool oldValue = (bool)e.OldValue; 
      bool newValue = (bool)e.NewValue; 

      if (oldValue == newValue) 
      { 
       return; 
      } 

      if (oldValue == false) 
      { 
       selector.PreviewMouseLeftButtonDown += listBox_PreviewMouseLeftButtonDown; 
      } 
      else 
      { 
       selector.PreviewMouseLeftButtonDown -= listBox_PreviewMouseLeftButtonDown; 
      } 
     } 

     private static void listBox_PreviewMouseLeftButtonDown(
      object sender, System.Windows.Input.MouseButtonEventArgs e) 
     { 
      var listBox = sender as ListBox; 
      if (listBox != null && listBox.SelectedItems.Count == 1) 
      { 
       UIElement container = listBox.ItemContainerGenerator 
        .ContainerFromItem(listBox.SelectedItems[0]) as UIElement; 

       if (container != null) 
       { 
        var pos = e.GetPosition(container); 
        var result = VisualTreeHelper.HitTest(container, pos); 
        if (result != null) 
        { 
         e.Handled = true; 
        } 
       } 
      } 
     } 
    } 
+0

Вы можете удалить свой вопрос или отметить свой ответ, как принято (после того, как, если я прав, 1 день) –

+0

Спасибо, Войцех Кулик, Приму свой ответ, в течение примерно 40 минут из-за ограничение^__ ^ – garek

Смежные вопросы