为什么我的命令绑定没有触发?

时间:2012-10-03 18:32:09

标签: wpf wpf-controls

我在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,但我现在没有时间。我需要在门外修复一些错误,这让我感到高兴。

感谢您的理解。

2 个答案:

答案 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中,我根本无法弄清楚如何将CommandTargetMenuItems的{​​{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都指向正确的控件,它们会正确启用和禁用。他们每个人都表现得很好。我很高兴。