1

There is something under the hood that I don't understand with ObservesCanExecute on DelegateCommand in prism. It has something to see with AutoProperties ... I think

I have a View with a button which is bound to a DelegateCommand in my viewmodel. For some reasons, in my view, I catch the the CanExecuteChanged event like this :

MyButton.Command.CanExecuteChanged += Command_CanExecuteChanged;

The question is, in my viewmodel, when I use autoproperties to declare IsEnabled, the event in the view is not fired. It is like if ObservesCanExecute doesn't work anymore. Is it normal ? Is there something I'm doing wrong ? I thought that AutoProperties and Properties were exactly the same ... Here is my ViewModel :

public class MainPageViewModel : ViewModelBase
{
    // VERSION 1 - It Works
    private bool _isEnabled = true;
    public bool IsEnabled
    {
        get { return _isEnabled; }
        set { SetProperty(ref _isEnabled, value); }
    }

    // VERSION 2 - Don't works
    // public bool IsEnabled {get; set; } = true;

    public DelegateCommand MyCommand { get; set; } = null;

    public MainPageViewModel(INavigationService navigationService)
        : base(navigationService)
    {
        Title = "Main Page";
        MyCommand = new DelegateCommand(Execute).ObservesCanExecute(() => IsEnabled);
    }

    private void Execute()
    {
        IsEnabled = !IsEnabled;
    }
}
Belight
  • 205
  • 2
  • 14

1 Answers1

1

ObservesCanExecuteChanged relies on INotifyPropertyChanged of the class containing the observed property.

This raises the event in case of a change and thus works

private bool _isEnabled = true;
public bool IsEnabled
{
    get { return _isEnabled; }
    set { SetProperty(ref _isEnabled, value); }
}

while this raises no event and does not work, as you observed:

public bool IsEnabled { get; set; }

I thought that AutoProperties and Properties were exactly the same

That's just plain wrong. An "AutoProperty" is a "Property", but that's it concerning the similarities. They may look alike from the outside of a class, but a property can just do anything, while an auto property is just a overly complicated field.

Haukinger
  • 10,420
  • 2
  • 15
  • 28
  • Ok. I am confused because when I declare a class implementing INotifyPropertyChanged, using autoproperties still fire the PropertyChanged event within the class. So I thought in this case it would also be the same. It's really confusing. – Belight Dec 25 '19 at 16:50
  • And Autoproperties are "enough complicated" - if I can say without offence - to be targeted in binding relations while normal fields can't. – Belight Dec 25 '19 at 16:54
  • In fact, the question is when can I use Autoproperties and when true properties are needed ? – Belight Dec 25 '19 at 17:18
  • `when I declare a class implementing INotifyPropertyChanged, using autoproperties still fire the PropertyChanged event within the class` pretty sure no, unless you're using something like Fody or Postsharp. – Haukinger Dec 25 '19 at 17:18
  • 1
    When you want anything but a field, create a real property, i.e. most of the time. Auto properties are normally seen only in passive data containers ("DTO"). Also, at least half of the properties I come across does not have a backing field, but instead redirects to some other class. – Haukinger Dec 25 '19 at 17:20