0

I have a window:

<Window x:Class="SomeNamespace.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="350" Width="525">
<Window.CommandBindings>
    <CommandBinding Command="ApplicationCommands.Copy"
        CanExecute="CommandCanExecute" Executed="CommandExecuted"/>
</Window.CommandBindings>
<DockPanel>
    <Menu DockPanel.Dock="Top">
        <MenuItem Header="File">
            <MenuItem Command="ApplicationCommands.Copy"/>
        </MenuItem>
    </Menu>
</DockPanel>
</Window>

With some code behind:

void CommandCanExecute(object sender, CanExecuteRoutedEventArgs e) {
    e.CanExecute = true;
}

void CommandExecuted(object sender, EventArgs e) {
    MessageBox.Show("Done!");
}

And everything works the way I expect. I can use the MenuItem or the Ctrl+C input binding to run my command.

But now my class has gotten too big, and I decide to refactor. So I moved my code behind to a user control. Here's my new Window:

<Window x:Class="SomeNamespace.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:my="clr-namespace:SomeNamespace"
    Height="350" Width="525">
<DockPanel>
    <Menu DockPanel.Dock="Top">
        <MenuItem Header="File">
            <MenuItem Command="ApplicationCommands.Copy"/>
        </MenuItem>
    </Menu>
    <my:UserControl1/>
</DockPanel>
</Window>

And my UserControl:

<UserControl x:Class="ImageDecompileSandbox.UserControl1"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <UserControl.CommandBindings>
        <CommandBinding Command="ApplicationCommands.Copy"
            CanExecute="CommandCanExecute" Executed="CommandExecuted"/>
    </UserControl.CommandBindings>
</UserControl>

Basically, everything is the same, except the CommandBinding was moved from the window to UserControl and the two command methods were pushed down to the user control.

Question: Why does the above not work? Why is my User Control's command not picked up by the window? How do I get the MenuItem / KeyBindings from the window to work with the command execution in the User Control?

benjamin.popp
  • 547
  • 1
  • 6
  • 20
  • 1
    if you create `CommandBinding` in `UserControl` then one of it's child controls must have focus in order for command to be triggered. – dkozl Jun 07 '14 at 19:43
  • Then what's the expected way to do this? How can I have commands that are application wide handled in a helper class? Is there a way to merge the command bindings from the child to the parent? – benjamin.popp Jun 08 '14 at 04:00
  • 1
    If you want it to execute in the whole window then you need to move `CommandBinding` back to `Window`. WPF will start from focused control and go up the visual tree to find some binding – dkozl Jun 08 '14 at 08:04
  • The expected way would be to add `CommandTarget` properties on your `MenuItem`'s, pointing to your user control. – ghord Oct 03 '16 at 21:21

1 Answers1

1

Thanks to dkozl, I was able to find a way to make this work.

The trick was indeed adding the CommandBinding back to the Window. Instead of declaring them all in the Window, which I can't do as the window doesn't know about the methods being used for Executed and CanExecute, I just added all the bindings from the control to the window:

CommandBindings.AddRange(_userControl1.CommandBindings);

I find this one-line hack to be exactly what I need, as it lets me keep the command controls and keybindings in the window while moving the command implementation to the control.

Thanks for the help dkozl!

benjamin.popp
  • 547
  • 1
  • 6
  • 20