我需要知道,如果SelectedItems在Ctrl或Shift按下時被填充。有沒有一種簡單的方法(無需創建新的控制模板)來獲取此信息?我更喜歡沒有代碼的解決方案。WPF ListBox SelectedItems確定按下Ctrl或Shift按鈕進行選擇
問候 Yannik
我需要知道,如果SelectedItems在Ctrl或Shift按下時被填充。有沒有一種簡單的方法(無需創建新的控制模板)來獲取此信息?我更喜歡沒有代碼的解決方案。WPF ListBox SelectedItems確定按下Ctrl或Shift按鈕進行選擇
問候 Yannik
我發現了一個最小代碼的解決方案。
主要的概念是,我將其附加到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
}
您可以連接最多選擇更改事件,並檢查是否修改鍵被按下了選擇。
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;
}
}
謝謝,但這正是我不想使用的代碼隱藏:-) – Yannik
爲什麼需要這些信息?只需將SelectionMode設置爲MultiExtended,您的SelectedItems就會被填充。 –
我需要從各種子視圖模型中收集選定的項目,並且在主視圖模型中,我希望按照所有子視圖模型的選擇進行操作。如果只選擇了一個項目(在所有子視圖模型上),我的行爲與選擇多個項目時不同。子視圖模型中的選擇綁定到綁定到ListBox的SelectedItems的自定義ObservableCollection。 – Yannik