Search code examples
c#wpfmvvmprism

Prism MVVM ObservesCanExecute - How Do I Nest (Logical AND Over) Simple Observable Properties


I'm fairly new to Prism, and I'm having trouble figuring out how to leverage the ObservesCanExecute (which allows me to not have to manually ask the command to re-calculate) for use with multiple properties. With a single property, this works like a charm! But I want to perform an "and" across all of my three properties.

Here is the code:

public ViewModel()
{
    MyCommand = new DelegateCommand(MyCommandHandler)
                .ObservesCanExecute(() => BoolOne)
                .ObservesCanExecute(() => BoolTwo)
                .ObservesCanExecute(() => BoolThree);
}
private bool _boolOne;
public bool BoolOne
{
    get => _boolOne;
    set => SetProperty(ref _boolOne, value);
}
...

What I'm experiencing is that once BoolThree is set to true, the button (attached to this command) is enabled without checking BoolOne and BoolTwo. How can I get this to also act like the command predicate is return BoolOne && BoolTwo && BoolThree


Solution

  • You will want to use ObservesProperty here instead of ObservesCanExecute. https://prismlibrary.com/docs/commanding.html

    Do not attempt to chain-register ObservesCanExecute methods. Only one property can be observed for the CanExcute delegate.

    You can chain-register multiple properties for observation when using the ObservesProperty method. Example: ObservesProperty(() => IsEnabled).ObservesProperty(() => CanSave).

    So you will want to change your code to this:

    MyCommand = new DelegateCommand(MyCommandHandler, MyCanExecuteMethod)
                .ObservesProperty(() => BoolOne)
                .ObservesProperty(() => BoolTwo)
                .ObservesProperty(() => BoolThree);
    
    private void MyCanExecuteMethod()
    {
        return BoolOne && BoolTwo && BoolThree;
    }
    

    This way when any of those properties change the RaiseCanExecuteChanged will be fired.