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