2013-06-24 32 views
2

我需要爲wpf中的ListBox控件實現自定義行爲。 這個想法是禁用取消選擇最後選定的元素。根據用戶使用鼠標點擊選定項目時的默認行爲,按住Ctrl鍵,選擇消失。我需要實現一些邏輯,以使用戶在最後選擇的項目上單擊鼠標+ Ctrl時,列表框不執行任何操作。防止在列表框中取消選擇最後選定項目的最佳方法

唯一的方法,我發現是訂閱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; 
       } 
      } 
     } 

但這種方法是不適合我,因爲在這種情況下,一些不期望呼叫發生在列表框。 SelectedItem被綁定到viewmodel屬性。

僞調用堆棧(當取消選擇所選項目):

  1. 的SelectedItem更改爲NULL

  2. listBox_SelectionChanged稱爲

  3. 的SelectedItem被設置爲先前值

我想要的就是這一步s 1和3不會發生。這很重要,因爲SelectedItem更改了一些長時間運行的異步操作。

謝謝,任何意見,將不勝感激!

回答

1

找到解決辦法。在ListBox上處理PreviewMouseLeftButtonDown對我來說工作正常。作爲附屬財產。

順便說一句:我可以以某種方式關閉這個問題嗎?

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

相關問題