什么可以破坏MenuItem上的WPF CommandBindings?

时间:2014-09-30 17:45:38

标签: wpf xaml data-binding command commandbinding

我有一些CommandBindings(在Window中)可以使用MenuItem s(通过"工作"我的意思是executed / {{ 1}}处理程序被称为,

我有其他人(在canexecute中)在分配给UserControl的{​​{1}}属性(调用处理程序)时有效 - 但与{{1 s(从不调用处理程序)。

我可以通过将每个绑定复制并粘贴到相应的Command中,使ButtonMenuItem中的MenuItem正确互动,如下所示:

CommandBinding

但这很愚蠢(见下文)。

我也可以通过将UserControl的命令绑定复制到MenuItem.CommandBindings构造函数中的窗口来使它们工作:

C#

<MenuItem
    Header="Select All"
    Command="{StaticResource SelectAllCommand}"
    >
    <MenuItem.CommandBindings>
        <CommandBinding
            Command="{StaticResource SelectAllCommand}"
            Executed="SelectAll_Executed"
            CanExecute="SelectAll_CanExecute"
            />
    </MenuItem.CommandBindings>
</MenuItem>

同样,这非常疯狂,但它似乎暗示在这里有一个背景因素。

我将控件XAML的相关位复制到以下测试XAML中以重现该问题,但问题并未重现。与我从中提取的生产代码不同,它可以按照您的预期运行:它是一个绑定,它被绑定,它调用方法。但是,将事件处理程序方法绑定到菜单项的命令的完全相同的方法在另一个(和不可比较的更复杂的)项目中的不同UserControl中失败。

XAML:

UserControl

C#:

Application.Current.MainWindow.CommandBindings.AddRange(this.CommandBindings);

所以问题是,哪些隐藏因素会导致UserControl无声地失败?你怎么调试这个?为什么我会在<UserControl x:Class="CommandTest.TestControl" 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.Resources> <ResourceDictionary> <RoutedUICommand x:Key="TestCommand" /> <ContextMenu x:Key="TestMenu"> <MenuItem Header="_Test" Command="{StaticResource TestCommand}" /> </ContextMenu> </ResourceDictionary> </UserControl.Resources> <UserControl.CommandBindings> <CommandBinding Command="{StaticResource TestCommand}" Executed="TestCommand_Executed" CanExecute="TestCommand_CanExecute" /> </UserControl.CommandBindings> <Grid> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <TextBox Width="200" ContextMenu="{StaticResource TestMenu}" /> </Grid> </UserControl> private void TestCommand_Executed(object sender, ExecutedRoutedEventArgs e) { MessageBox.Show("Test Command", "Test", MessageBoxButton.OK, MessageBoxImage.Information); } private void TestCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = true; e.Handled = true; } 之间看到同一控件中相同命令绑定的完全不同的行为?是因为CommandBinding是资源吗?但在我的测试代码中,它是一种资源,一切正常。

更新:

Another solution^Wworkaround:明确将Button设置为MenuItem。呵呵。

1 个答案:

答案 0 :(得分:1)

我怀疑测试项目的可视树与干扰命令路由的生产项目之间存在细微差别。路由命令沿可视树搜索命令处理程序,最多可以采用两条路径。

来自this MSDN Magazine article

  

通常,命令调用程序在可视树中它自己的位置和可视树的根之间查找命令绑定。如果找到一个,绑定命令处理程序将确定是否启用该命令,并在调用该命令时调用该命令。如果命令连接到工具栏或菜单中的控件(或者更常见的是设置FocusManager.IsFocusScope = true的容器),那么一些额外的逻辑运行也会沿着从根到焦点的可视树路径查看命令绑定的元素。