Page 1 of 1

Using the INotifyPropertyChanged functionality

#1 Sergio Tapia  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1252
  • View blog
  • Posts: 4,168
  • Joined: 27-January 10

Posted 07 January 2011 - 08:04 PM

*
POPULAR

Or, "a control/class/userControl doesn't have an event I need to use!"

At work this morning, I needed to find a ColorPicker to use on our Windows Forms application. I searched for a bit and finally settled on one built using WPF.

Downloaded the control and with some tweaking I managed to have it working and it fit in great with the look and feel of our application. Then we hit a snag. I needed to somehow detect when a different color was picked, and wouldn't you know it the control didn't have the event for this use-case.

After some digging around I found the INotifyPropertyChanged interface and man was it good. It fit like a glove and long story short I created an event I could hook into easily whenever a color was picked. I now have a nice reusable Windows Forms userControl we can use anywhere on our application.

The reason for this backstory is that hopefully you can see the benefit of using this interface. I had no idea it existed but after today I'm glad I found it.

We're going to build a little example on a Console application showing it's functionality.

Create a new Console application and create a Person class with some properties for it:

public class Person
{
    private string _name = string.Empty;
    private string _lastName = string.Empty;
    private string _address = string.Empty;

    public string Name
    {
        get { return this._name; }
        set
        {
            this._name = value;
        }
    }

    public string LastName
    {
        get { return this._lastName; }
        set
        {
            this._lastName = value;
        }
    }

    public string Address
    {
        get { return this._address; }
        set
        {
            this._address = value;
        }
    }
}




Sergio, what's with the funky formatting?! Patience, you'll see!

Now let's have the class implement the INotifyPropertyChanged interface:

public class Person : INotifyPropertyChanged


You'll have to reference the System.ComponentModel:

using System.ComponentModel;


Now implement the interface contract:

public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string info)
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(info));
    }
}



Cool, now we have an event handler!

Let's wire this class up so when a property is changed in the class it'll let the handler know.

public string Name
{
    get { return this._name; }
    set
    {
        this._name = value;
        NotifyPropertyChanged("Name");
    }
}

public string LastName
{
    get { return this._lastName; }
    set
    {
        this._lastName = value;
        NotifyPropertyChanged("LastName");
    }
}

public string Address
{
    get { return this._address; }
    set
    {
        this._address = value;
        NotifyPropertyChanged("Address");
    }
}


So now our class is wired up correctly for usage. Let's head on to the Main method of Program.cs


class Program
{
    static void Main(string[] args)
    {
        Person sergio = new Person();
        sergio.PropertyChanged += new PropertyChangedEventHandler(sergio_PropertyChanged);

        sergio.Name = "Sergio";
        Console.ReadLine();

        sergio.Name = "Serg";
        Console.ReadLine();
    }

    static void sergio_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        Console.WriteLine("Something changed!");
        Console.WriteLine(e.PropertyName);
    }
}



That wraps it up, hopefully you realize the HUGE benefit this can bring to your code and how you handle events and unwilling objects. ;)

If you see something can be improved please leave some feedback.

Is This A Good Question/Topic? 6
  • +

Replies To: Using the INotifyPropertyChanged functionality

#2 CodingSup3rnatur@l-360  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 991
  • View blog
  • Posts: 971
  • Joined: 30-September 10

Posted 09 January 2011 - 03:34 AM

Damn, you beat me to it. I was going to write a tutorial on this as soon as I got some spare time :). It's a very useful interface and it seems to me that you explained it very clearly.

I have used this interface in conjunction with data binding on a few WinForm apps I have made in the past. For example, if your making a simple game (tic tac toe, for example), and you have a Score class that manages the logic for the scoring system (just for arguements sake and clarity). Score contains 3 properties (1 for Naughts' score, one for Crosses' and one for Draws), you can have that Score class implement the INotifyPropertyInterface, fulfil the contract as follows:

public class Scores : INotifyPropertyChanged
    {
        private int draws = 0;
        private int naughts = 0;
        private int crosses = 0;
        
        public event PropertyChangedEventHandler PropertyChanged;

        public int Crosses
        {
            get { return this.crosses; }
            private set
            {
                this.crosses = value;
                this.RaisePropertyChangedEvent("Crosses");
            }
        }
        public int Naughts
        {
            get { return this.naughts; }
            private set
            {
                this.naughts = value;
                this.RaisePropertyChangedEvent("Naughts");
            }
        }

        public int Draws
        {
            get { return this.draws; }
            private set
            {
                this.draws = value;
                this.RaisePropertyChangedEvent("Draws");
            }
        }

        private void RaisePropertyChangedEvent(string propertyName)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (PropertyChanged != null) handler(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
        }



Then, in the main form, all you would have to do is create three labels (again, just for example), and bind their Text properties to the properties of the Score class:

public partial class Form1 : Form
    {

        private Score scores = new Scores();

        public Form1()
        {
            InitializeComponent();
            
            this.crosses_lbl.DataBindings.Add("Text", scores, "Crosses");
            this.naughts_lbl.DataBindings.Add("Text", scores, "Naughts");
            this.draws_lbl.DataBindings.Add("Text", scores, "Draws");    
        }
    }



The first arguement in Add() is the property of the control that you want to bind to, the second is the data source (in this case, an instance of the Score class) and the third is the name of the property in the data source that you want to bind to. You don't even have to manually register with and handle the PropertyChanged event!

Now, every time your internal logic for the game updates the scores in the Score class, the changes will automatically be displayed on the UI. And so you have a score board and all you have to do is concentrate on the logic of finding a winner and updating the Score properties. The UI is handled for you!

The above is just a basic example to clearly illustrate the point, but it is a very helpful feature in certain situations :).

This post has been edited by CodingSup3rnatur@l-360: 09 January 2011 - 10:39 AM

Was This Post Helpful? 2
  • +
  • -

Page 1 of 1