Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement INotifyPropertyChanged in C# 6.0?

Tags:

The answer to this question has been edited to say that in C# 6.0, INotifyPropertyChanged can be implemented with the following OnPropertyChanged procedure:

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

However, it isn't clear from that answer what the corresponding property definition should be. What does a complete implementation of INotifyPropertyChanged look like in C# 6.0 when this construction is used?

like image 941
T.C. Avatar asked Feb 23 '16 15:02

T.C.


People also ask

Why do we use INotifyPropertyChanged?

The INotifyPropertyChanged interface is used to notify clients, typically binding clients, that a property value has changed. For example, consider a Person object with a property called FirstName .

What is Propertychangedeventhandler C#?

Represents the method that will handle the PropertyChanged event raised when a property is changed on a component.

What does RaisePropertyChanged do?

The RaisePropertyChanging event is used to notify UI or bound elements that the data has changed. For example a TextBox needs to receive a notification when the underlying data changes, so that it can update the text you see in the UI.

What is RaisePropertyChanged WPF?

RaisePropertyChanged("User"); From MSDN: The PropertyChanged event can indicate all properties on the object have changed by using either null or String. Empty as the property name in the PropertyChangedEventArgs. (No need to refresh all the Properties in this case)


2 Answers

After incorporating the various changes, the code will look like this. I've highlighted with comments the parts that changed and how each one helps

public class Data : INotifyPropertyChanged {      public event PropertyChangedEventHandler PropertyChanged;     protected void OnPropertyChanged([CallerMemberName] string propertyName = null)     {         //C# 6 null-safe operator. No need to check for event listeners         //If there are no listeners, this will be a noop         PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));     }      // C# 5 - CallMemberName means we don't need to pass the property's name     protected bool SetField<T>(ref T field, T value,     [CallerMemberName] string propertyName = null)     {         if (EqualityComparer<T>.Default.Equals(field, value))              return false;         field = value;         OnPropertyChanged(propertyName);         return true;     }      private string name;     public string Name     {         get { return name; }         //C# 5 no need to pass the property name anymore         set { SetField(ref name, value); }     } } 
like image 199
Panagiotis Kanavos Avatar answered Oct 06 '22 16:10

Panagiotis Kanavos


I use the same logic in my project. I have a base class for all view models in my app:

using System.ComponentModel; using System.Runtime.CompilerServices;  public class PropertyChangedBase : INotifyPropertyChanged {     public event PropertyChangedEventHandler PropertyChanged;      protected void OnPropertyChanged([CallerMemberName] string propertyName = "")     {         PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));     } } 

Every view model inherits from this class. Now, in the setter of each property I just need to call OnPropertyChanged().

public class EveryViewModel : PropertyChangedBase {     private bool initialized;     public bool Initialized     {         get         {             return initialized;         }         set         {             if (initialized != value)             {                 initialized = value;                 OnPropertyChanged();             }         }     } 

Why does it work?

[CallerMemberName] is automatically populated by the compiler with the name of the member who calls this function. When we call OnPropertyChanged from Initialized, the compiler puts nameof(Initialized) as the parameter to OnPropertyChanged

Another important detail to keep in mind

The framework requires that PropertyChanged and all properties that you're binding to are public.

like image 37
Amadeusz Wieczorek Avatar answered Oct 06 '22 14:10

Amadeusz Wieczorek