我在WPF应用程序中定义了许多自定义命令:
public class MyCommands {
public static RoutedUICommand CopyPlateCommand;
public static RoutedUICommand PreviousRecordCommand;
public static RoutedUICommand NextRecordCommand;
public static RoutedUICommand SearchCommand;
public static RoutedUICommand SearchPlateCommand;
}
我有一个UserControl
ContextMenus
使用了其中一些命令:
<UserControl x:Class="MyNamespace.UserControl1"
. . . >
<UserControl.Resources>
<ContextMenu x:Key="ContextMenu" HorizontalAlignment="Left">
<MenuItem Header="Copy Plate" Command="{Binding cs:MyCommands.CopyPlateCommand}" />
<MenuItem Header="Search Plate" Command="{Binding cs:MyCommands.SearchPlateCommand}" />
</ContextMenu>
<ContextMenu x:Key="TextBoxMenu" HorizontalAlignment="Left">
<MenuItem Header="Copy" Command="{Binding Copy}" />
<MenuItem Header="Copy Plate" Command="{Binding cs:MyCommands.CopyPlateCommand}" />
<MenuItem Header="Search Plate" Command="{Binding cs:MyCommands.SearchPlateCommand}" />
</ContextMenu>
</UserControl.Resources>
. . .
</UserControl>
UserControl1
中没有命令绑定。
我有另一个UserControl
,其中包含UserControl1
的实例。它还包含CommandBindings
,其中包含UserControl1
中的上下文菜单中包含的命令:
<UserControl x:Class="MyNamespace.UserControl2"
. . . >
<UserControl.CommandBindings>
<CommandBinding Command="Copy" CanExecute="CopyCommand_CanExecute" Executed="CopyCommand_Executed" />
<CommandBinding Command="cs:MyCommands.CopyPlateCommand" CanExecute="CopyPlateCommand_CanExecute" Executed="CopyPlateCommand_Executed" />
<CommandBinding Command="cs:MyCommands.SearchPlateCommand" CanExecute="CopyPlateCommand_CanExecute" Executed="SearchPlateCommand_Executed" />
</UserControl.CommandBindings>
. . .
<c:UserControl1 . . . />
我在命令的各种处理程序中放置了断点,但断点永远不会被击中。我做错了什么?我是否必须将命令绑定放入UserControl1
?
不,我的程序不使用MVVM。在我听说MVVM之前,我开始了这个项目。我打算在将来的某个时候将它转换为MVVM,但我现在没有时间。我需要在门外修复一些错误,这让我感到高兴。
感谢您的理解。
贝
答案 0 :(得分:3)
您的Command类需要公开公共属性,而不是公共字段。
您必须绑定到属性而不是字段,因为大多数绑定基于 ComponentModel PropertyDescriptor模型。属性公开了绑定引擎启用绑定所需的元数据。
绑定到公共语言运行时(CLR)对象:
您可以绑定到公共属性,子属性以及 任何公共语言运行时(CLR)对象的索引器。绑定 引擎使用CLR反射来获取属性的值。 或者,实现ICustomTypeDescriptor或具有的对象 注册的TypeDescriptionProvider也可以使用绑定引擎。
取自binding source specification。
以下示例:
public class MyCommands {
public static RoutedUICommand CopyPlateCommand { get; set; }
public static RoutedUICommand PreviousRecordCommand { get; set; }
public static RoutedUICommand NextRecordCommand { get; set; }
public static RoutedUICommand SearchCommand { get; set; }
public static RoutedUICommand SearchPlateCommand { get; set; }
}
在调试模式下运行应用程序时,请检查“输出”窗口是否存在绑定错误。
答案 1 :(得分:0)
虽然我在课堂上创建的RoutedUICommand
对象是字段而不是正确的,但这还不足以使程序正常工作。在XAML中,我根本无法弄清楚如何将CommandTarget
中MenuItems
的{{1}}属性设置为UserControl1
。
我确实让它工作了,但我最终在代码隐藏中完成了它。我做的是我写了一个名为UserControl2
的辅助方法:
FixMenuItems
然后我写了一个名为private void FixMenuItems( FrameworkElement element, Func<MenuItem, bool> condition, FrameworkElement target ) {
foreach ( MenuItem menuItem in element.ContextMenu.Items ) {
if ( condition( menuItem ) ) {
menuItem.CommandTarget = target;
}
}
}
的公共方法:
SetupCommandTargets
然后,在public void SetupCommandTargets( FrameworkElement target, Func<MenuItem, bool> condition ) {
FixMenuItems( Control1, condition, target );
FixMenuItems( Control2, condition, target ); . . .
}
和UserControl1
的构造函数中,我根据需要调用public函数,因为我将一些控件的处理程序移动到UserControl2
,因为这些处理程序需要访问该类的私人财产。
我还必须删除UserControl1
Bindings
属性上的Command
。我能够在XAML中执行MenuItems
。只是CommandBindings
我无法开始工作。
完成所有这些更改后,现在一切正常。 CommandTargets
都指向正确的控件,它们会正确启用和禁用。他们每个人都表现得很好。我很高兴。