C# 5–Making INotifyPropertyChanged Easier

There are times when I think my friends in the C# team are just listening to me gripe before adding a cool new feature that solves the problem.  (I have never quite outgrown the assumption that the world revolves around me).

A couple years ago I grew really tired of having to create the same old same old when it came to public properties,

private int _myValue;
public int MyValue
{
  get { return _myValue; }
  set { _myValue = value; }
}

 

No sooner did I whine about this, then along came automatic properties and life became much easier.  The above boiled down to

private int MyValue { get; set; }

 

My new gripe (and yours, no doubt) was the work involved in sending in the name of the calling property for INotifyPropertyChanged.  It became common practice to write a helper method that took the name of the property and fed it to the PropertyChanged event, but it was a string being passed around and one tiny typo and your property did not update the UI.  Here’s the old way…

 

private string _name;

public string Name
{
    get { return _name; }
    set
    {
        _name = value;
        RaisePropertyChanged("Name");
    }
}

private void RaisePropertyChanged( string caller)
{
  if (PropertyChanged != null)
  {
    PropertyChanged( this, new PropertyChangedEventArgs( caller ) );
  }
}

 

Notice that the Name property has to send “Name” to the RaisePropertyChanged helper method. 

With C# 5, this problem is solved (Hoot!) by adding an attribute to the argument in RaisePropertyChanged:  [CallerMemberName]  The new syntax, which is much less error prone is:

private string _name;

public string Name
{
    get { return _name; }
    set
    {
        _name = value;
        RaisePropertyChanged();
    }
}

private void RaisePropertyChanged(
    [CallerMemberName] string caller = "" )
{
  if (PropertyChanged != null)
  {
    PropertyChanged( this, new PropertyChangedEventArgs( caller ) );
  }
}

 

Notice that you no longer include the name of the property when calling RaisePropertyChanged.  You just call it, and due to the attribute, the called method figures out what the caller member name is and places that into the string parameter.  Sweet.

Here’s the complete C# for the Employee class for Win 8, followed by the XAML to test it on Win 8…

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace PropertyChanged
{
    class Employee : INotifyPropertyChanged
    {
        private string _name;
        public string Name
        {
            get { return _name; }
            set
            {
                _name = value;
                RaisePropertyChanged();
            }
        }

        public void SetName( string newName )
        {
            Name = newName;
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void RaisePropertyChanged( [CallerMemberName] string caller = "")
        {
            if ( PropertyChanged != null )
            {
                PropertyChanged( this, new PropertyChangedEventArgs( caller ) );
            }
        }
    }
}

 

The XAML…

<Page
    x:Class="PropertyChanged.MainPage"
    IsTabStop="false"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:PropertyChanged"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <StackPanel Orientation="Horizontal">
        <TextBlock
            Name="NameDisplay"
            Text="{Binding Name}" />
            <Button
                Height="100"
                Width="200"
                Content="Change name"
                Name="ChangeName"
                Click="ChangeName_Click_1" />
        </StackPanel>
    </Grid>
</Page>

 

The code-behind…

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;


namespace PropertyChanged
{

    public sealed partial class MainPage : Page
    {

        Employee emp = new Employee();

        public MainPage()
        {
            this.InitializeComponent();
        }

       
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            DataContext = emp;
            emp.SetName( "Joe" );
        }

        private void ChangeName_Click_1( object sender, RoutedEventArgs e )
        {
            emp.SetName( "Bob" );
        }
    }
}

About Jesse Liberty

Jesse Liberty has three decades of experience writing and delivering software projects and is the author of 2 dozen books and a couple dozen online courses. His latest book, Building APIs with .NET will be released early in 2025. Liberty is a Senior SW Engineer for CNH and he was a Senior Technical Evangelist for Microsoft, a Distinguished Software Engineer for AT&T, a VP for Information Services for Citibank and a Software Architect for PBS. He is a Microsoft MVP.
This entry was posted in Essentials, Languages, Windows 8 and tagged . Bookmark the permalink.

77 Responses to C# 5–Making INotifyPropertyChanged Easier

Comments are closed.