1

The question says it all. When using Xamarin this pattern comes up :

public string Property
        {
            get
            {
                return this.propertyField;
            }

            set
            {
                if (value != this.propertyField)
                {
                    this.propertyField = value;
                    NotifyPropertyChanged();
                }
            }
        }

And it seems like I I have to do this for each property I have. Any way to avoid repetion?

Moha the almighty camel
  • 4,327
  • 4
  • 30
  • 53

2 Answers2

5

There is!

The easiest way to do this is to install the PropertyChanged.Fody package (Nuget).

After you have installed this, you should have a weavers.xml file in the root of your project. Open it, to make sure it contains this:

<?xml version="1.0" encoding="utf-8" ?>
<Weavers>
  <PropertyChanged/>
</Weavers>

Now, you just have to add the INotifyPropertyChanged interface on classes where you want to implement the notify functionality and that's it! For all public properties, the boilerplate code is generated at compile-time.

From the README:

You write this

public class Person : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public string GivenNames { get; set; }
    public string FamilyName { get; set; }
    public string FullName => $"{GivenNames} {FamilyName}";
}

What gets generated/compiled is this

public class Person : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    string givenNames;
    public string GivenNames
    {
        get => givenNames;
        set
        {
            if (value != givenNames)
            {
                givenNames = value;
                OnPropertyChanged("GivenNames");
                OnPropertyChanged("FullName");
            }
        }
    }

    string familyName;
    public string FamilyName
    {
        get => familyName;
        set 
        {
            if (value != familyName)
            {
                familyName = value;
                OnPropertyChanged("FamilyName");
                OnPropertyChanged("FullName");
            }
        }
    }

    public string FullName => $"{GivenNames} {FamilyName}";

    public virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

As you can see there is some cool stuff going on here. Dependencies between propeties are detected and accounted for. Also the shothand property notation is supported.

Furthermore, there are some attributes available to control how properties are treated. A few:

  • [DoNotNotify] exclude a property from generating the notify code
  • [AlsoNotifyFor(nameof(OtherProperty)] or [DependsOn(nameof(OtherProperty)] With this attributes you can also create a dependency between properties.

Examples can be found on the wiki on Github

Gerald Versluis
  • 30,492
  • 6
  • 73
  • 100
0

You could take a look at PostSharp.

If you do not need any business logic withing your properties' getters or setters, you can also take a look at the ObservableDictionary approach. Like this one

In brief, it's a dictionary that sends PropertyChanged when an entry is changed, so you can make bindings to it's entries.

NikoR
  • 508
  • 3
  • 7