Data-binding To A Simple C# class (WPF or Silverlight)

Seeking the perfect fit
One of your most frequent needs when composing a GUI dialog is to ‘bind’ a property of one of your widgets to some kind of information source. WPF’s data binding capabilities provide a way to accomplish this very easily in XAML for a range of scenarios. Here’s a (very) simplified example.

Say you want a TextBox to get it’s text from an object of your own C# class. Let’s contrive a gnarly little sample class to serve as our data source that just holds a single property:

 

namespace DesignForge
{
    class MyClass
    {
        public string FirstName
        {
            get { return _firstName; }
            set { _firstName = value; }
        }

        private string _firstName = "Naira";
    }
}

 

Consider this to be your “view-model”; in your XAML you bind to it using this syntax:

<TextBox Text="{Binding Path=FirstName}" />

What you are saying with this, in effect, is to get it’s value from the FirstName property of the binding source. You can get values only from properties – not from instance variables.

You can leave out the “Path” part – leaving this..


<TextBox Text="{Binding FirstName}" />

 

Where do we specify the binding source? One way is to simply do that in code; in the constructor after InitializeComponent, or in your event handler for the Loaded event:

public MainWindow()
{
    InitializeComponent();

    // Set the binding source here.
    MyClass viewModel = new MyClass();
    this.DataContext = viewModel;
}

 

Now it should work – when your Window pops up on the screen your TextBox fetches it’s text content from the FirstName property of your MyClass. Juuuust peachy.

But.. if you leave it as it is here, your TextBox won’t update it’s text whenever the FirstName property changes! Why? Because it has no way of knowing; it fetches the property value just once as it initializes itself and renders itself on-screen.

Let’s fix that. We can use DependencyProperties, but for now why don’t we just reach for the simplest way available.

Change your source class to implement the INotifyPropertyChanged interface. This makes it send a notification to your XAML-defined TextBox of any important changes whenever you set a new value for that property. Here’s that same source class, with two essential changes. Take careful note of the change in your FirstName property…

 

using System.ComponentModel; // for INotifyPropertyChanged

namespace DesignForge
{
    public class MyClass : INotifyPropertyChanged
    {
        // This next region of code, is step ONE (of two) of what you need
        // to support the INotifyPropertyChanged interface.
        // I usually just copy it from a previous piece of code – it just works,
        // or, put it within a base-class.
        #region INotifyPropertyChanged implementation

        public event PropertyChangedEventHandler PropertyChanged;

        protected void Notify(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion INotifyPropertyChanged implementation

        // This is step TWO.
        // For each of your properties whose changes you want to track
        // (that is, to cause the data bindings to update),
        // add the call to Notify within the setter as I did below.
        // The string that you put as the parameter to Notify,
        // must to be exactly the same as the name of the property
        // (just copy-paste it and it'll rarely be a source of mistake).
        public string FirstName
        {
            get { return _firstName; }
            set
            {
                // Do nothing unless the new value is different..
                if (value != _firstName)
                {
                    // Set the value.
                    _firstName = value;
                    // This next line is the only change within this property.
                    // Notify anyone who cares about this.
                    Notify("FirstName");
                }
            }
        }

        private string _firstName = "Naira";
    }
}

 

Now run your app and you should be seeing your GUI fields updating themselves to track the changes in your source class. This is the simplest example of a one-way binding and handles probably the majority of cases of this nature. Subsequent posts will cover more scenarios. Please shoot back a note to me if you spot any mistakes, problems or additional insight.

James W. Hurst

About these ads

About James W Hurst

a professional software designer since the beginning days of the desktop cptr and uC-controlled avionics, I today am focusing on C# and F# for building desktop and online applications under WPF, and Silverlight/ASP.NET along with the requisite HTML/CSS/JavaScript/Ajax for web applications. My database expertise is focused on Microsoft SQL Server and db4o, and my main area of interest is Artificial Intelligence and vision.
This entry was posted in C#, Software Design, The .NET Framework, WPF and tagged . Bookmark the permalink.

18 Responses to Data-binding To A Simple C# class (WPF or Silverlight)

  1. Tom says:

    Hi im using your tutorial for one of my school project. But i wonder if my source class content has an ilist in it and the ilist contains objects how do i bind the objects data in the ilist. // Tom and thanks for the great tutorial

  2. James Hurst says:

    Hi Tom – sorry for not having seen your question earlier. Are you still on that school project? In general yes – you can bind to an IList if the data is an appropriate fit. Post a description of what you’re trying to do, if you wish.

  3. Josh says:

    very interesting, glad i ran into your posting. קידום אתרים

  4. James says:

    thanks for the help!
    I have a question though… Lets say I wanted to make the name appear as Adam Smith, where in the initialize method do I assign the value to the src object?

    • Please explain a bit further – do you mean, where do you assign the string “Adam Smith” to the object you’re using as a view-model, to which you have bound some property of some WPF control?

  5. Sutton says:

    The app runs, but I’m not seeing anything visual happening when I change the text. What should I be seeing? Should something be changing every time I add a letter or delete a letter from the name?

  6. kast says:

    Hi,
    at first thanks a lot for this great post. It made my day ;)
    Perhaps you can give me a hint on my problem…
    I have a lot of similar variables in my “view model”. I would like to put them into an array, but i can’t figure out how to define the get and set methods… Any hint on this ?

    • Hello kast, there are several ways to implement your scenario, if I understand you correctly. One is to simply define a distinct property in your view-model for each of those variables, and within the getter of each property you index into the appropriate place within your array to fetch the variable’s value (I am thinking this would be the simplest and clearest way). Or you could include a parameter within the binding expression to tell it how far to index into the array. Or, use a value-converter. If you want to share more details of what you’re trying to do with me, perhaps I can be of further help. Best of wishes, jh

  7. thanks you helped me alot

  8. Mikhail says:

    Thanks alot. Not the first article I’ve read on this topic but seems rather last ;-?
    Seems others have forget the ‘advice’ of initialize DataContext by view-model instance…

  9. Artour says:

    Made my day :)

  10. Ernie says:

    Thank you! You also made my day.

  11. Tarec says:

    Works flawlesly, thank you very much for your help :)

  12. ddev says:

    Thats the best explanation of data binding i have found so far !!!
    Thank you very much for your post, very useful and very well explained.

  13. Jean Offenberg says:

    Nice, thanks, however public was added to myclass later on, I took it out and it works as well.

  14. marcel says:

    In my case PropertyChanged is always null so it never triggers the event. what am I doing wrong?
    Thanks

  15. Srinivasan says:

    Nice one. Very basic about Notification handling and Data binding.

    This is the stuff which beginners should know.

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