2

我在我的 WPF 应用程序中定义了许多自定义命令:

public class MyCommands {

    public static RoutedUICommand CopyPlateCommand;

    public static RoutedUICommand PreviousRecordCommand;

    public static RoutedUICommand NextRecordCommand;

    public static RoutedUICommand SearchCommand;

    public static RoutedUICommand SearchPlateCommand;

}

我有一个使用这些命令的其中一些UserControlContextMenus

<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,但我现在没有时间。我需要修复一些错误,这让我很受挫。

感谢您的理解。

托尼

4

2 回答 2

3

您的 Command 类需要公开公共属性,而不是公共字段。

您必须绑定到属性而不是字段,因为大多数绑定基于 ComponentModel PropertyDescriptor 模型。属性公开绑定引擎启用绑定所需的此元数据。

绑定到公共语言运行时 (CLR) 对象:

您可以绑定到任何公共语言运行时 (CLR) 对象的公共属性、子属性以及索引器。绑定引擎使用 CLR 反射来获取属性的值。或者,实现 ICustomTypeDescriptor 或已注册 TypeDescriptionProvider 的对象也可以与绑定引擎一起使用。

取自绑定源规范

下面的例子:

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; }

}

在调试模式下运行应用程序时,检查“输出”窗口是否存在绑定错误。

于 2012-10-03T21:42:42.623 回答
0

虽然RoutedUICommand我在课堂上创建的对象是字段而不是属性,但这还不足以让程序正常工作。我根本不知道如何在 XAML中将in的CommandTarget属性设置为.MenuItemsUserControl1UserControl2

我确实让它工作了,但我最终在代码隐藏中完成了它。我所做的是我编写了一个名为的辅助方法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 );        . . .
}

然后,在 and 的构造函数中UserControl1UserControl2我根据需要调用公共函数,因为我将一些控件的处理程序移到其中,UserControl1因为这些处理程序需要访问该类的私有属性。

我还必须删除Bindings. 我能够在 XAML 中完成。只是我无法上班。CommandMenuItemsCommandBindingsCommandTargets

进行所有这些更改后,现在一切正常。MenuItems全部指向正确的控件,它们会正确启用和禁用。他们每个人都执行适当的操作。我很高兴。

于 2012-10-04T16:17:17.860 回答