首页 > 解决方案 > WPF Prism CompositeCommand 禁用按钮

问题描述

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

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

我尝试向 中添加琐碎CanExecute的方法DeleteCommands,但这并没有解决它。

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

我想也许它正在禁用,因为我的DelegateCommandshave 参数和 aCompositeCommand似乎无法接受任何CommandParameters参数,但我消除了 the 中的参数,DelegateCommands但这并没有解决问题。

查看.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()
    {
        ...
    }
}

标签: wpfprism

解决方案


您必须使用该方法将DelegateCommands 注册到 a 。直接将它们添加到集合中不起作用,因为它每次都会返回一个新的集合实例。CompositeCommandRegisterCommandRegisteredCommands

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

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

监控命令活动是完全不同的事情。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; }

推荐阅读