WPF listbox with contextmenu canexecute not called until something selected
commandbinding, contextmenu, listbox, wpf
Solution
This is a known bug as mentioned here. If there is no focused element in the window's main focus scope, the `CanExecute` routing will stop at the `ContextMenu`, so it will not reach to the `CommandBinding` on the Window, one workaround is to bind `MenuItem`'s `CommandTarget` to the main window, as following code demonstrates:
<ListBox.ContextMenu>
<ContextMenu>
<MenuItem Command="SelectAll"
CommandTarget="{Binding Path=PlacementTarget,RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}">
</MenuItem>
</ContextMenu>
</ListBox.ContextMenu>
Below is the complete code:
<UserControl x:Class="ListBoxStyle.ListBoxUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.CommandBindings>
<CommandBinding Command="SelectAll" CanExecute="SelectAll_CanExecute" Executed="SelectAll_Executed"/>
</UserControl.CommandBindings>
<Grid>
<ListBox x:Name="listbox"
Background="Transparent"
SelectionMode="Extended"
ScrollViewer.VerticalScrollBarVisibility="Auto">
<ListBox.ContextMenu>
<ContextMenu>
<MenuItem Command="SelectAll"
CommandTarget="{Binding Path=PlacementTarget,RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}">
</MenuItem>
</ContextMenu>
</ListBox.ContextMenu>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Background="Transparent">
<CheckBox Name="cbEnabled" IsChecked="{Binding Enabled, Mode=TwoWay}" Margin="0,2,0,0"/>
<TextBlock Text="{Binding}" Padding="5,0,0,0"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</UserControl>
Problem
I have a ListBox the ItemTemplate bound to an ObservableCollection of my items. At the moment, I'm trying to implement Cut/Copy/Paste/SelectAll (To keep it short, I'll just show selectall here...) ``` <UserControl.CommandBindings> <CommandBinding Command="SelectAll" CanExecute="SelectAll_CanExecute" Executed="SelectAll_Executed"/> </UserControl.CommandBindings> <ListBox x:Name="listbox" ItemsSource="{Binding}" Background="Transparent" SelectionMode="Extended" ScrollViewer.VerticalScrollBarVisibility="Auto"> <ListBox.ContextMenu> <ContextMenu> <MenuItem Command="SelectAll" /> </ContextMenu> </ListBox.ContextMenu> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal" Background="Transparent"> <CheckBox Name="cbEnabled" IsChecked="{Binding Enabled, Mode=TwoWay}" Margin="0,2,0,0"/> <TextBlock Text="{Binding Name}" Padding="5,0,0,0"/> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> ``` this is the codebehind for canexecute: ``` private void SelectAll_CanExecute(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = listbox.Items.Count > 0; e.Handled = true; } ``` when I first run the program and right-click in the listbox, the "Select All" context menu is always disabled (and SelectAll_CanExecute is never called) until I select something. Is there any way to get this to work like it seems it should? (and without either auto-selecting the first item or making the user have to do it) Thanks!