2015-04-28 48 views
0

我需要知道,如果SelectedItems在Ctrl或Shift按下時被填充。有沒有一種簡單的方法(無需創建新的控制模板)來獲取此信息?我更喜歡沒有代碼的解決方案。WPF ListBox SelectedItems確定按下Ctrl或Shift按鈕進行選擇

問候 Yannik

+0

爲什麼需要這些信息?只需將SelectionMode設置爲MultiExtended,您的SelectedItems就會被填充。 –

+0

我需要從各種子視圖模型中收集選定的項目,並且在主視圖模型中,我希望按照所有子視圖模型的選擇進行操作。如果只選擇了一個項目(在所有子視圖模型上),我的行爲與選擇多個項目時不同。子視圖模型中的選擇綁定到綁定到ListBox的SelectedItems的自定義ObservableCollection。 – Yannik

回答

0

我發現了一個最小代碼的解決方案。

主要的概念是,我將其附加到MainWindow中的KeyDown和KeyUp事件,並在MainViewModel上設置屬性「CurrentKeyboardKeyPressed」,該屬性將按下的按鍵信息傳播給子視圖模型,然後觸發自定義事件與一個特殊的選擇類,它具有當前按鍵的信息。

發佈的源代碼被重新縮短並且根本不運行。如果有人對工作解決方案感興趣,只需問我,我會通過電子郵件發送。

MainWindow.xaml.cs

public partial class MainWindow : Window 
{ 
    private readonly MainWindowViewModel _mainWindowViewModel; 

    public MainWindow() 
    { 
     _mainWindowViewModel = new MainWindowViewModel(); 
     InitializeComponent(); 

     DataContext = _mainWindowViewModel; 
    } 

    private void MainWindow_OnKeyDown(object sender, KeyEventArgs e) 
    { 
     if (e.Key == Key.LeftCtrl || e.Key == Key.RightCtrl) 
     { 
      _mainWindowViewModel.CurrentKeyboardKeyPressed = PressedKeyboardKey.Ctrl; 
      return; 
     } 

     if (e.Key == Key.LeftShift || e.Key == Key.RightShift) 
     { 
      _mainWindowViewModel.CurrentKeyboardKeyPressed = PressedKeyboardKey.Shift; 
     } 
    } 

    private void MainWindow_OnKeyUp(object sender, KeyEventArgs e) 
    { 
     _mainWindowViewModel.CurrentKeyboardKeyPressed = PressedKeyboardKey.None; 
    } 
} 

MainWindowViewModel.cs

public class MainWindowViewModel : ViewModelBase 
{ 
    // child view models 
    private readonly ObservableCollection<TTSViewModel> _ttsViewModels; 

    private PressedKeyboardKey _currentKeyboardKeyPressed; 

    public EventHandler<KeyboardKeyPressedEventArgs> CurrentKeyboardKeyPressedChanged; 

    public MainWindowViewModel() 
    { 
     _ttsViewModels = new ObservableCollection<TTSViewModel>(); 
    } 

    public PressedKeyboardKey CurrentKeyboardKeyPressed 
    { 
     get { return _currentKeyboardKeyPressed; } 
     set 
     { 
      if (_currentKeyboardKeyPressed != value) 
      { 
       _currentKeyboardKeyPressed = value; 
       OnCurrentKeyboardKeyPressedChanged(_currentKeyboardKeyPressed); 
      } 
     } 
    } 

    // create child view models 
    public void PopulateTTSList(int itemsToCreated) 
    { 
     for (int i = 0; i < itemsToCreated; i++) 
     { 
      var tts = new TTSViewModel("TTS " + i); 

      tts.FractionSelectionChanged += OnTTSFractionSelectionChanged; 
      CurrentKeyboardKeyPressedChanged += tts.CurrentKeyboardKeyPressedChanged; 
      _ttsViewModels.Add(tts); 
     } 
    } 

    private void OnCurrentKeyboardKeyPressedChanged(PressedKeyboardKey currentKeyboardKeyPressed) 
    { 
     var handler = CurrentKeyboardKeyPressedChanged; 
     if (handler != null) 
     { 
      handler(this, new KeyboardKeyPressedEventArgs(currentKeyboardKeyPressed)); 
     } 
    } 

    // selection changed handler for each child view model 
    private void OnTTSFractionSelectionChanged(object sender, ItemSelectionChangedEventArgs fractionSelectionChangedEventArgs) 
    { 
     var sendingTTS = sender as TTSViewModel; 
     if (fractionSelectionChangedEventArgs.Selection.PressedKeyOnSelection == PressedKeyboardKey.None) 
     { 
      // single selection action goes here 
      // .... 
     } 
     else 
     { 
      // multi selection action goes here 
      // .... 
     } 
    } 
} 

TTSViewModel.cs(子視圖模型)

public class TTSViewModel : ViewModelBase 
{ 
    private readonly SmartObservableCollection<FractionViewModel> _currentlySelectedfractions; 
    public EventHandler<ItemSelectionChangedEventArgs> FractionSelectionChanged; 
    private PressedKeyboardKey _currentKeyboardKeyPressed; 

    public TTSViewModel() 
    { 
     _currentlySelectedfractions = new SmartObservableCollection<FractionViewModel>(); 
     _currentlySelectedfractions.CollectionChanged += CurrentlySelectedfractionsOnCollectionChanged; 
    } 

    public void CurrentKeyboardKeyPressedChanged(object sender, KeyboardKeyPressedEventArgs currentKeyboardKeyPressedEventArgs) 
    { 
     _currentKeyboardKeyPressed = currentKeyboardKeyPressedEventArgs.CurrentKeyboardKeyPressed; 
    } 

    private void CurrentlySelectedfractionsOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs) 
    { 
     if (FractionSelectionChanged != null) 
     { 
      if (notifyCollectionChangedEventArgs.Action == NotifyCollectionChangedAction.Replace && notifyCollectionChangedEventArgs.NewItems != null) 
      { 
       var removed = _oldSelectedfractions.Except(_currentlySelectedfractions); 
       var added = _currentlySelectedfractions.Except(_oldSelectedfractions); 

       var selection = new Selection<FractionViewModel>(added, removed, _currentKeyboardKeyPressed); 

       _oldSelectedfractions.Clear(); 
       foreach (var currentlySelectedfraction in _currentlySelectedfractions) 
       { 
        _oldSelectedfractions.Add(currentlySelectedfraction); 
       } 

       var selectionChangedArgs = new ItemSelectionChangedEventArgs(selection); 
       FractionSelectionChanged(this, selectionChangedArgs); 
      } 
     } 
    } 
} 

Selection.cs

public sealed class Selection<T> 
{ 
    private readonly List<T> _added; 
    private readonly List<T> _removed; 
    private readonly PressedKeyboardKey _currentKeyboardKeyPressed; 

    public Selection() 
    { 
     _added = new List<T>(); 
     _removed = new List<T>(); 
    } 

    /// <summary> 
    /// Initializes a new instance of the <see cref="Selection{T}" /> class. 
    /// </summary> 
    /// <param name="addedItems">[NotNull]</param> 
    /// <param name="removedItems">[NotNull]</param> 
    /// <param name="currentKeyboardKeyPressed">The current keyboard key pressed.</param> 
    public Selection(IEnumerable<T> addedItems, IEnumerable<T> removedItems, PressedKeyboardKey currentKeyboardKeyPressed) 
    : this() 
    { 
     _added.AddRange(addedItems); 
     _removed.AddRange(removedItems); 
     _currentKeyboardKeyPressed = currentKeyboardKeyPressed; 
    } 

    public IReadOnlyList<T> Added 
    { 
     get { return _added; } 
    } 

    public IReadOnlyList<T> Removed 
    { 
     get { return _removed; } 
    } 

    public PressedKeyboardKey PressedKeyOnSelection 
    { 
     get { return _currentKeyboardKeyPressed; } 
    } 
} 

KeyboardKeyPressedEventArgs.cs

public sealed class KeyboardKeyPressedEventArgs : EventArgs 
{ 
    public KeyboardKeyPressedEventArgs(PressedKeyboardKey currentKeyboardKeyPressed) 
    { 
     CurrentKeyboardKeyPressed = currentKeyboardKeyPressed; 
    } 

    public PressedKeyboardKey CurrentKeyboardKeyPressed { get; private set;  } 
} 

ItemSelectionChangedEventArgs.cs

public sealed class ItemSelectionChangedEventArgs : EventArgs 
{ 
    public ItemSelectionChangedEventArgs(Selection<FractionViewModel> newSelection) 
    { 
     Selection = newSelection; 
    } 

    public Selection<FractionViewModel> Selection { get; private set; } 
} 

PressedKeyboardKey.cs

public enum PressedKeyboardKey 
{ 
    None, 
    Ctrl, 
    Shift 
} 
1

您可以連接最多選擇更改事件,並檢查是否修改鍵被按下了選擇。

void listBox_SelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     var isCtrlorShiftDown = (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl) || Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift)); 
     if (isCtrlorShiftDown) 
     { 
      // Write your Logic Here; 
     } 
    } 
+0

謝謝,但這正是我不想使用的代碼隱藏:-) – Yannik