【问题标题】:WPF Prism CompositeCommand disables buttonWPF Prism CompositeCommand 禁用按钮
【发布时间】:2020-09-01 15:11:16
【问题描述】:

我有两个要通过单击按钮触发的命令。所以我创建了一个CompositeCommand,用它注册了我的两个命令,并绑定到我的按钮。我的命令是DelegateCommands

问题是按钮被禁用,我无法启用它。

我尝试将琐碎的 CanExecute 方法添加到 DeleteCommands,但这并没有解决问题。

我尝试在CompositeCommand 构造函数中将monitorCommandActivity 设置为true。

我想可能是因为我的DelegateCommands 有参数,而CompositeCommand 似乎不能接受任何CommandParameters,所以它可能被禁用了,但我消除了DelegateCommands 中的参数,但事实并非如此解决问题。

View.xaml:

    <TextBlock Text="Theme:" />
    <telerik:RadComboBox x:Name="_themeComboBox"
                         ItemsSource="{Binding ThemeList}"
                         DisplayMemberPath="Name"
                         SelectedItem="{Binding SelectedTheme, Mode=TwoWay}" />
    <telerik:RadButton Content="Apply"
                       Command="{Binding ThemeApplyAndSaveCommand}" />

ViewModel.cs:

public class ViewModel
{
    public ViewModel(ILogger logger, ...)
    {
        ThemeList = _userSettingsService.GetThemeList();

        // Configure the theme Apply button to both select and save the theme
        ThemeApplyAndSaveCommand.RegisterCommand(ThemeApplyCommand);
        ThemeApplyAndSaveCommand.RegisterCommand(ThemeSaveCommand);

        // Activate the user's preferred theme
        SelectedTheme = _userSettingsService.GetThemePreference(securityContext.User);
        ThemeApplyCommand.Execute();

        logger.Debug("    ThemeApplyCommand.CanExecute: {canExecute}", ThemeApplyCommand.CanExecute());
        logger.Debug("    ThemeSaveCommand.CanExecute: {canExecute}", ThemeSaveCommand.CanExecute());
        logger.Debug("    ThemeApplyAndSaveCommand.CanExecute: {canExecute}", ThemeApplyAndSaveCommand.CanExecute(null));
    }


    public CompositeCommand ThemeApplyAndSaveCommand => new CompositeCommand();

    public DelegateCommand ThemeApplyCommand => new DelegateCommand(ExecuteThemeApplyCommand);

    public DelegateCommand ThemeSaveCommand => new DelegateCommand(ExecuteThemeSaveCommand);

    private void ExecuteThemeApplyCommand()
    {
        ...
    }

    private void ExecuteThemeSaveCommand()
    {
        ...
    }
}

【问题讨论】:

    标签: wpf prism


    【解决方案1】:

    您必须使用RegisterCommand 方法将DelegateCommands 注册到CompositeCommand。直接将它们添加到RegisteredCommands 集合中是行不通的,因为它每次都会返回一个新的集合实例。

    var compositeCommand = new CompositeCommand();
    compositeCommand.RegisterCommand(MyDelgateCommand);
    compositeCommand.RegisterCommand(MyOtherDelegateCommand);
    

    如果所有活动命令都可以执行,则CompositeCommand 仅返回truetrue。您必须确保在注册的命令应该更新其活动时调用RaiseCanExecuteChanged,以便复合命令也可以重新评估其活动。

    监控命令活动是完全不同的事情。 Prism 中的视图或视图模型可以实现IActiveAware 以了解它们何时在区域中被激活和停用。 DelegateCommands 也实现了这个接口,所以它们也可以通过对应的视图模型来激活和停用。如果您没有明确启用监控命令活动,则命令将被视为处于活动状态。

    想象一个将活动文档保存在选项卡控件中的命令。您可以将选项卡的保存命令注册到公共保存CompositeCommand,但仅当它们位于活动选项卡上时才激活它们。在这种情况下,监控命令的活动将只考虑CanExecute 的活动命令,并在调用命令时只执行它们。


    更新您发布的代码。相应的命令属性每次都返回新命令。在构造函数中初始化复合命令和其他命令。

    public ViewModel(ILogger logger, ...)
    {
       ThemeList = _userSettingsService.GetThemeList();
    
       // Configure the theme Apply button to both select and save the theme
       ThemeApplyAndSaveCommand = new CompositeCommand();
       ThemeApplyCommand = new DelegateCommand(ExecuteThemeApplyCommand);
       ThemeSaveCommand = new DelegateCommand(ExecuteThemeSaveCommand);
    
       ThemeApplyAndSaveCommand.RegisterCommand(ThemeApplyCommand);
       ThemeApplyAndSaveCommand.RegisterCommand(ThemeSaveCommand);
    
       // ...the rest of the constructor code.
    }
    
    public CompositeCommand ThemeApplyAndSaveCommand { get; }
    
    public DelegateCommand ThemeApplyCommand { get; }
    
    public DelegateCommand ThemeSaveCommand { get; }
    

    【讨论】:

    • 我应该提到我确实使用了RegisterCommand()。我什至对监控可执行性(或者你怎么称呼它)都不感兴趣。此命令始终可执行。
    • 我必须手动激活命令吗?这对我来说没有任何意义,为什么按钮会被禁用,只是我用包装它的复合命令替换按钮的命令。
    • @MattGregory 如果您没有明确启用命令监控,所有命令都将被视为处于活动状态。如果您只创建两个没有任何CanExecute 或始终true 的委托命令并将它们注册到复合命令,它将按预期工作,按钮将被启用。
    • 是的,这就是我所期望的,但它不起作用。我用CompositeCommand 注册DelegateCommands,当我在每一个上记录CanExecute 的结果时,紧接着,两个DelegateCommands' 返回trueCompositeCommand 的返回false。我想我现在要放弃 CompositeCommands。
    • 哦!我知道为什么!因为每次访问我使用箭头运算符的属性时,它们都会返回一个新对象!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-23
    • 1970-01-01
    • 2017-06-06
    • 1970-01-01
    • 1970-01-01
    • 2011-02-23
    • 1970-01-01
    相关资源
    最近更新 更多