#1,097 – Getting Items in Context Menu to Correctly Use Command Binding

Let’s say that you set up command bindings for a main Window in an application and then use the command for some control (e.g. a Button) and also within a ContextMenu.  (Assume that the GreetUser_CanExecute method always returns true).

    <Window.CommandBindings>
        <CommandBinding Command="{x:Static loc:MainWindow.GreetUserCommand}"
                        CanExecute="GreetUser_CanExecute"
                        Executed="GreetUser_Executed"/>
    </Window.CommandBindings>

    <Window.ContextMenu>
        <ContextMenu>
            <MenuItem Command="{x:Static loc:MainWindow.GreetUserCommand}"/>
        </ContextMenu>
    </Window.ContextMenu>

    <StackPanel>
        <TextBox Name="txtSomeText"
                 Width="220" Height="25" Margin="10"/>
        <Button HorizontalAlignment="Center"
                Padding="10,5" Margin="10"
                Content="{Binding RelativeSource={RelativeSource Self}, Path=Command.Text}"
                Command="{x:Static loc:MainWindow.GreetUserCommand}"/>
    </StackPanel>

If you run this code and right-click on the window to bring up the context menu, the MenuItem is greyed out.  It’s not binding correctly to our CanExecute method.  The Button, on the other hand, did find the binding.

1097-001

The fix for this is to set the CommandTarget for the MenuItem to the PlacementTarget of the parent ContextMenu–the Window.  The MenuItem definition becomes:

            <MenuItem Command="{x:Static loc:MainWindow.GreetUserCommand}"
                      CommandTarget="{Binding Path=PlacementTarget, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}"/>

1097-002

 

Advertisements