Posted by: Zeeshan Amjad | July 26, 2013

Simple way to implement INotifyPropertyChanged wih CallerMemberName


We already saw how to implement INotifyPropertyChanged here. Since beginning this approach has a problem of hardcoded string, i.e. we have to pass the name of the property as a string. Although the name of the property can be retrieved by using some expression or reflection, but that is not only complicate code , but also make it little slower.

Finally in .Net 4.5 Microsoft introduced one simple way to avoid passing the string while implementing INotifyPropertyChanged interface and the solution is CallerMemberName attribute. If we specify this attribute with the parameter of a function, then it will be populated with the caller function. Along with this, Microsoft also introduced CallerFilePathAttribute and CallerLineNumberAttribute, which are self explanatory.

Now we have to change our RaisePropertyChanged method little bit to use this new feature.

Code Snippet
#region NotifyPropertyChanged Methods

public void RaisePropertyChanged([CallerMemberName] string propertyName = null)
{
    PropertyChangedEventHandler handler = this.PropertyChanged;

    if (handler != null)
    {
        handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

public event PropertyChangedEventHandler PropertyChanged;

#endregion

 

Now the propertyName parameter takes the default value, therefore we can simply ignore in the properties implementation and can never be out of sync.

Here is a complete XAML code of the project.

Code Snippet
<Window x:Class="NotifyPropertyChangeDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml&quot;
        Title="INotifyPropertyChange" Height="300" Width="400">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <TextBlock Margin="5" Grid.Column="0" Grid.Row="0" VerticalAlignment="Center">
            Enter First Number
        </TextBlock>
        <TextBox Margin="5" Grid.Column="1" Grid.Row="0"
                 VerticalAlignment="Center" Text="{Binding First}"/>
        <TextBlock Margin="5" Grid.Column="0" Grid.Row="1" VerticalAlignment="Center">
            Enter Second Number
        </TextBlock>
        <TextBox Margin="5" Grid.Column="1" Grid.Row="1"
                 VerticalAlignment="Center" Text="{Binding Second}"/>
        <TextBlock Margin="5" Grid.Column="0" Grid.Row="2" VerticalAlignment="Center">
            The number of primes in between theese numbare are
        </TextBlock>
        <TextBlock Margin="5" Grid.Column="1" Grid.Row="2"
                   VerticalAlignment="Center" Text="{Binding Result}"/>
        <Button Margin="5" Grid.Column="0" Grid.Row="3" Click="Button_Click">
            Exit
        </Button>
        <Button Margin="5" Grid.Column="1" Grid.Row="3" Click="Button_Click_1">
            Calculate
                </Button>
    </Grid>
</Window>

 

And here is a complete C# code of the project

Code Snippet
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;

namespace NotifyPropertyChangeDemo
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private Data data = new Data();

        public MainWindow()
        {
            InitializeComponent();

            DataContext = data;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            int count = 0;

            for (int i = data.First; i <= data.Second; i++)
            {
                if (isPrime(i))
                {
                    count++;
                }
            }

            data.Result = count;
        }

        private bool isPrime(int no)
        {
            if (no < 2)
                return false;

            for (int i = 2; i < no / 2; i++)
            {
                if (no % i == 0)
                    return false;
            }

            return true;
        }
    }

    public class Data : INotifyPropertyChanged
    {
        private int first;
        private int second;
        private int result;

        public int First
        {
            get
            {
                return first;
            }
            set
            {
                first = value;
                RaisePropertyChanged();
            }
        }

        public int Second
        {
            get
            {
                return second;
            }
            set
            {
                second = value;
                RaisePropertyChanged();
            }
        }

        public int Result
        {
            get
            {
                return result;
            }
            set
            {
                result = value;
                RaisePropertyChanged();
            }
        }

        #region NotifyPropertyChanged Methods

        public void RaisePropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;

            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

    }
}

 

This is the output of a program.

CallerMemberNameOutput

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: