我有一些CommandBindings
(在Window
中)可以使用MenuItem
s(通过"工作"我的意思是executed
/ {{ 1}}处理程序被称为,
我有其他人(在canexecute
中)在分配给UserControl
的{{1}}属性(调用处理程序)时有效 - 但与{{1 s(从不调用处理程序)。
我可以通过将每个绑定复制并粘贴到相应的Command
中,使Button
与MenuItem
中的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
。呵呵。
答案 0 :(得分:1)
我怀疑测试项目的可视树与干扰命令路由的生产项目之间存在细微差别。路由命令沿可视树搜索命令处理程序,最多可以采用两条路径。
通常,命令调用程序在可视树中它自己的位置和可视树的根之间查找命令绑定。如果找到一个,绑定命令处理程序将确定是否启用该命令,并在调用该命令时调用该命令。如果命令连接到工具栏或菜单中的控件(或者更常见的是设置FocusManager.IsFocusScope = true的容器),那么一些额外的逻辑运行也会沿着从根到焦点的可视树路径查看命令绑定的元素。