如果我将ICommand绑定到WPF中的控件,它将根据命令的CanExecute状态启用/禁用。我知道,在我想“分组”的ICommand的所有CanExcecute实现中,可以使用一个布尔字段来禁用多个命令的执行。我的问题是,我应该这样做还是以某种方式在XAML中这样做?有没有“标准”的方法来做呢?任何.NET类来管理它?
oyxsuwqo1#
在.NET Framework中没有这样的类,但是你可以看看CompositeCommand类是如何在Prism中实现的。关于docs:它维护子命令列表(DelegateCommand示例)。CompositeCommand类的Execute方法只是依次调用每个子命令的Execute方法。CanExecute方法同样调用每个子命令的CanExecute方法,但是如果任何子命令无法执行,CanExecute方法将返回false。换句话说,默认情况下,CompositeCommand只能在所有子命令都可以执行时执行。使用CompositeCommand类的RegisterCommand方法关联子命令:
DelegateCommand
CompositeCommand
Execute
CanExecute
false
RegisterCommand
public DelegateCommand UpdateCommand { get; private set; } public ViewModel() { UpdateCommand = new DelegateCommand(Update); ApplicationCommands.SaveCommand.RegisterCommand(UpdateCommand); }
6ju8rftf2#
我提出了一个新的解决方案(CommandGroup类),它以线程安全的方式同步执行标志。在CommandGroup中创建多个命令。当执行一个命令时,设置标志。当另一个命令尝试执行时,它首先检查标志:如果同一组的另一个命令已经在运行,则后面的命令将不会开始执行。Interlocked.CompareExchange用于检查命令当前是否正在执行,并在一个原子操作中切换执行标志(_currentState)。一旦执行完成,_currentState将再次使用线程安全操作(Interlocked.Exchange)恢复。
CommandGroup
Interlocked.CompareExchange
_currentState
Interlocked.Exchange
if (Interlocked.CompareExchange(ref _currentState, Running, NotRunning) == NotRunning) { Debug.WriteLine($"CommandGroup: Command execution started"); try { await execute(p); } finally { Debug.WriteLine($"CommandGroup: Command execution finished"); Interlocked.Exchange(ref _currentState, NotRunning); } } else { Debug.WriteLine($"CommandGroup: Command execution skipped"); }
更多的解释和完整的源代码可以在这里找到:https://github.com/PrismLibrary/Prism/issues/2890
2条答案
按热度按时间oyxsuwqo1#
在.NET Framework中没有这样的类,但是你可以看看CompositeCommand类是如何在Prism中实现的。
关于docs:
它维护子命令列表(
DelegateCommand
示例)。CompositeCommand
类的Execute
方法只是依次调用每个子命令的Execute
方法。CanExecute
方法同样调用每个子命令的CanExecute
方法,但是如果任何子命令无法执行,CanExecute
方法将返回false
。换句话说,默认情况下,CompositeCommand
只能在所有子命令都可以执行时执行。使用
CompositeCommand
类的RegisterCommand
方法关联子命令:6ju8rftf2#
我提出了一个新的解决方案(
CommandGroup
类),它以线程安全的方式同步执行标志。在CommandGroup中创建多个命令。当执行一个命令时,设置标志。当另一个命令尝试执行时,它首先检查标志:如果同一组的另一个命令已经在运行,则后面的命令将不会开始执行。Interlocked.CompareExchange
用于检查命令当前是否正在执行,并在一个原子操作中切换执行标志(_currentState
)。一旦执行完成,_currentState
将再次使用线程安全操作(Interlocked.Exchange
)恢复。更多的解释和完整的源代码可以在这里找到:https://github.com/PrismLibrary/Prism/issues/2890