Prism MVVM中ObservesCanExecute如何实现多属性逻辑与判断
嘿,我懂你遇到的困扰了——Prism的ObservesCanExecute链式调用多个单属性的时候,并不会自动帮你把它们的逻辑做与运算,反而会出现你看到的这种「只要最后一个属性为true就启用命令」的问题。其实要实现三个布尔值的逻辑与判断,有两种简单的解决办法:
方法一:直接用组合逻辑的Lambda表达式
Prism的ObservesCanExecute支持解析包含多个属性的Lambda表达式,它会自动监听所有被引用属性的变化,并且把表达式的结果作为CanExecute的判断依据。你只需要把三个属性的逻辑与直接写到Lambda里就行:
public ViewModel() { MyCommand = new DelegateCommand(MyCommandHandler) .ObservesCanExecute(() => BoolOne && BoolTwo && BoolThree); } private bool _boolOne; public bool BoolOne { get => _boolOne; set => SetProperty(ref _boolOne, value); } private bool _boolTwo; public bool BoolTwo { get => _boolTwo; set => SetProperty(ref _boolTwo, value); } private bool _boolThree; public bool BoolThree { get => _boolThree; set => SetProperty(ref _boolThree, value); }
这样设置后,只有当BoolOne、BoolTwo、BoolThree同时为true时,命令的CanExecute才会返回true,绑定的按钮才会启用。
方法二:使用计算属性(适合复杂逻辑场景)
如果你的CanExecute逻辑以后可能变得更复杂,或者想把判断逻辑单独抽离出来,可以创建一个只读的计算属性,然后让命令监听这个属性:
public ViewModel() { MyCommand = new DelegateCommand(MyCommandHandler) .ObservesCanExecute(() => CanExecuteMyCommand); } private bool _boolOne; public bool BoolOne { get => _boolOne; set { if (SetProperty(ref _boolOne, value)) { // 当BoolOne变化时,通知计算属性的状态变更 RaisePropertyChanged(nameof(CanExecuteMyCommand)); } } } private bool _boolTwo; public bool BoolTwo { get => _boolTwo; set { if (SetProperty(ref _boolTwo, value)) { RaisePropertyChanged(nameof(CanExecuteMyCommand)); } } } private bool _boolThree; public bool BoolThree { get => _boolThree; set { if (SetProperty(ref _boolThree, value)) { RaisePropertyChanged(nameof(CanExecuteMyCommand)); } } } // 计算属性,返回三个布尔值的逻辑与结果 public bool CanExecuteMyCommand => BoolOne && BoolTwo && BoolThree;
这种方法的优势在于,你可以在CanExecuteMyCommand中扩展更复杂的判断逻辑,而且所有子属性变化时都会触发这个计算属性的通知,命令会自动重新计算CanExecute状态。
为什么之前的写法不对?
你之前多次链式调用ObservesCanExecute,每次传入单个属性。Prism在这种场景下,后续的调用会覆盖之前设置的CanExecute判断逻辑,最终只会以最后一个传入的属性(也就是BoolThree)作为命令启用的依据,所以才会出现只要BoolThree为true就启用按钮的情况。
内容的提问来源于stack exchange,提问作者Thomas
相关产品推荐
相关产品推荐

