3

I have a hard time understanding the difference between those 3 things when creating a project using Xamarin.Forms or MAUI. I know what these are - INotifyPropertyChanged is an interface you need to implement when you want to use bindings in XAML, BindableObject is Xamarin.Forms class that implements said interface and ObservableObject is a class found in Xamarin Community Toolkit that also implements that interface. I just don't really understand the differences between them (especially the latter two) and when you would use any of them? I have read different tutorials and they all say different things - that you need to implement the interface yourself (so your viewmodel implements it), that your viewmodel needs to inherit from BindableObject, or - if you're using Xamarin Community Toolkit (which you probably should use/are using) - inherit from ObservableObject. But - like I said - why should you use any of the solutions mentioned above over the others?

If you implement INotifyPropertyChanged interface Visual Studio (or ReSharper extension, I'm not sure which one) automatically implements the method it needs to and adds this code:

public event PropertyChangedEventHandler PropertyChanged;

protected virtual void PropertyChanged([CallerMemberName] string propertyName = null)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

But it makes your code longer/uglier, so I understand why you would want to only inherit from a class that already implements that interface. But then why some people say you should always implement it yourself? Is there a difference when you implement it yourself or inherit from a class that already implements it? Also, if you decide to inherit from a class - why use either one over the other one? The documentation of Xamarin.Forms is quite good in this regard, but it doesn't acknowledge the existence of Xamarin Community Toolkit and the Xamarin Community Toolkit documentation doesn't answer my question and doesn't say why you should use their ObservableObject over Xamarin.Form's built-in BindableObject.

Razwill
  • 85
  • 3
  • 12

2 Answers2

5

I think your confusion is stemming from the difference between Bindable and Observable.

You're mostly correct about INotifyPropertyChanged. It's the abstract concept of a value changing, not the concrete implementation of that change. It's not just used for XAML though, it can be used for anything. But what do I mean by that?

Different parts of a system will care about why a value is changed for different reasons. A class that sits and silently logs data to a text file based on the value of something changing, is very different to a class that updates an application's user interface when something changes.

INotifyPropertyChanged is merely a mechanism to facilitate that change notification, it's nothing more.

Circling back to the difference between ObservableObject and BindableObject, they're simply for different use cases.

Take a look at the documentation I linked to above. See how many methods exist on the BindableObject class? Notice how OnPropertyChanged is just one of many methods on the BindableObject, but on ObservableObject it's one of only two?

BindableObject is used as a base class for elements. Changing the state of a button to disable it when it's clicked, for example. Or updating the text value of a Label in response to something changing.

ObservableObject can be used as a base class for anything that needs to notify some other class about a value change. As you correctly pointed out, it's to stop you needing to write that boilerplate INotifyPropertyChanged implementation all the time.

There's much more to this subject, but I don't want to bombard you with a huge amount of information.

If you're looking for some real world examples, study how the MVVM design pattern leverages the concept of classes communicating changes to one another.

  • Thank you! Your answer really helped me and cleared the confusion. Especially thank you for providing useful links. But I have one more question though, just to be sure - does this mean that my ViewModels should inherit from `ObservableObject`, as there is no need to inherit from `BindableObject`? Also - does this mean that if I follow the MVVM pattern there's no need for me to ever inherit from `BindableObject`, because the code-behind files for XAML already inherit from `ContentPage` (which indirectly inherits from `BindableObject`)? – Razwill Feb 23 '22 at 14:21
  • 1
    Not a problem, thanks for marking it as accepted. I'm trying to get a reputation for providing great Xamarin help to people here :) The answer is your question is "Yes. MOST of the time". A good rule of thumb is "ViewModels are ObservableObjects, Views are Pages, Elements on Views are BindableObjects". –  Feb 23 '22 at 14:30
  • 1
    Excellent answer. Minor correction re *"Views are Pages"*: Pages and Views are VisualElements. All Elements are BindableObjects. – ToolmakerSteve Dec 06 '22 at 01:58
  • @ToolmakerSteve Thanks! Fair correction as well. I was trying not to get bogged down into the nitty gritty, but a few months removed from writing this answer, I think it's right to mention. –  Dec 06 '22 at 08:31
3

There is some confusion I think about the different classes:

  • Xamarin.Forms.BindableObject is meant to be used to create something like a custom view with bindable properties. It also implements INotifyPropertyChanged, but I don't think you should use it for a ViewModel.

  • The ObservableObject from the community toolkit can be used as a base class for any class you like to use with data binding, you don't need to implement it yourself.

  • If you have some custom requirements for handling the OnPropertyChanged, you do need to implement the interface yourself, but if you just want to have default behaviour, ObservableObject is perfectly fine.

Skittles86
  • 96
  • 1
  • 4