MenuItem in Window, CommandBinding in UserControl

2019-09-15 05:20发布

问题:

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?

回答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!