Список WPF и выберите все

Я хочу создать простой ListBox и выбрать SelectAll в качестве контекстного меню. Однако похоже, что ListBox имеет встроенную обработку для SelectAll, которую я не могу заставить работать, но мешает моей попытке реализовать SelectAll.

Весь мой XAML:

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Window.CommandBindings>
        <CommandBinding Command="ApplicationCommands.SelectAll"
                        Executed="SelectAllExecuted" />
    </Window.CommandBindings>
    <DockPanel>
        <CheckBox DockPanel.Dock="Top">My Checkbox</CheckBox>
        <ListBox Name="listBox" SelectionMode="Multiple">
            <ListBox.ContextMenu>
                <ContextMenu>
                    <MenuItem Command="ApplicationCommands.SelectAll" />
                </ContextMenu>
            </ListBox.ContextMenu>
        </ListBox>                
    </DockPanel>
</Window>

SelectAllExecuted - это просто:

private void SelectAllExecuted(object sender, ExecutedRoutedEventArgs e)
{
    listBox.SelectAll();
}

Control + A работает, если список не находится в фокусе. Элемент контекстного меню работает правильно. Но Control + A отказывается работать, если список сфокусирован.

Мне кажется, что я борюсь с списком, но мне не нужно.

Изменить. Кажется, все мои проблемы связаны с Multiple SelectionMode. Если я установил его в Extended, все будет работать, однако я не хочу его в расширенном режиме.

Ответ 1

ListBox, похоже, имеет собственную внутреннюю команду для комбинации клавиш Ctrl + A, как объясняет Марко Чжоу. Мы также можем проверить это, поставив точку останова в обработчиках Execute и Preview Execute. Как вы увидите, ни один из них не достигнут, когда ListBox имеет фокус и нажата комбинация клавиш. Даже когда мы устанавливаем SelectionMode в Extended, и мы можем наблюдать, как элементы выбираются командой, обработчики еще не достигнуты. К счастью, однако, мы можем переопределить существующий InputGesture, просто переназначив его. Мы можем сделать это в ListBox, чтобы избавиться от пользовательской обработки Ctrl + A и переназначить его в команде ApplicationCommands.SelectAll.

<ListBox Name="listBox"
         SelectionMode="Multiple">
    <ListBox.InputBindings>
        <KeyBinding Command="ApplicationCommands.SelectAll"
                    Modifiers="Ctrl"
                    Key="A" />
    </ListBox.InputBindings>            
    ...
</ListBox>

После добавления KeyBinding в ListBox, когда он имеет фокус, теперь он переместит Ctrl + A обратно к существующей команде SelectAll и SelectAllExecuted.

Ответ 2

Для таких, как я, которые заканчивают делать все в коде:):)

listBox.InputBindings.Add(new KeyBinding(ApplicationCommands.SelectAll, 
                          new KeyGesture(Key.A, ModifierKeys.Control)));
listBox.CommandBindings.Add(new CommandBinding(ApplicationCommands.SelectAll, (_sender, _e) =>
{
    listBox.SelectAll();
}));