WPF ListBox SelectedItems确定按下Ctrl或Shift以进行选择

时间:2015-04-28 08:09:57

标签: wpf listbox

我需要知道,如果在按下Ctrl或Shift时,SelectedItems被填满了。是否有一种简单的方法(无需创建新的控制模板)来获取此信息?我更喜欢没有代码的解决方案。

祝你好运 Yannik

2 个答案:

答案 0 :(得分: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;
        }
    }

答案 1 :(得分:0)

我找到了一个代码最少的解决方案。

主要概念是,我附加到MainWindow中的KeyDown和KeyUp事件,并在MainViewModel上设置属性“CurrentKeyboardKeyPressed”,它将按下的键信息传播到子视图模型,后者又触发自定义事件一个特殊的Selection类,它具有当前按下的键信息。

已发布的源代码已缩短,并且根本无法运行。如果有人对工作解决方案感兴趣,请问我,我会给它发电子邮件。

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
}