WPF Prism CompositeCommand 禁用按钮

WPF Prism CompositeCommand disables button

我有两个要通过单击按钮触发的命令。所以我创建了一个 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()
    {
        ...
    }
}

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

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

A CompositeCommand only returns true for CanExecute, if all active commands can execute.您必须确保在注册的命令应该更新其 activity 时调用 RaiseCanExecuteChanged,以便复合命令也可以重新评估其 activity。

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

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


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

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