views:

1183

answers:

1

I want to create a simple ListBox and have SelectAll as a context menu item. However it seems that ListBox has some sort of inbuilt handling for SelectAll that I can't get working, but is interfering with my attempt to implement SelectAll.

My entire XAML is this:

<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 is simply this:

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

Control+A works if the listbox isn't in focus. The context menu item works correctly. But Control+A refuses to work if the listbox is focused.

I feel like I'm fighting against the listbox, but I shouldn't need to.

Edit: It seems my entire problems are with the Multiple SelectionMode. If I set it to Extended then everything works, however I don't want it in extended mode.

+4  A: 

ListBox seems to have it's own internal command for the Ctrl+A key combination, as Marco Zhou explains. We can also test this by attempting to place a breakpoint in the Execute and Preview Execute handlers. As you will see neither is reached when the ListBox has focus and the key combination is pressed. Even when we set the SelectionMode to Extended and we can watch the items be selected by the command the handlers still are not reached. Thankfully though, we can override an existing InputGesture by just re-assigning it. We can do this in the ListBox to get rid of it's custom Ctrl+A handling, and re-assign it to the ApplicationCommands.SelectAll command.

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

Once the KeyBinding is added to the ListBox, when it has focus it will now route Ctrl+A back to your existing SelectAll command and SelectAllExecuted.

rmoore
That's awesome. Thanks, works perfectly.
Ray