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

When composing a WPF view sometimes you need 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 trivial example.

Let’s 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 HurstOnWpfDataBinding1
{
    public class Person
    {
        public string FirstName
        {
            get { return _firstName; }
            set { _firstName = value; }
        }
 
        private string _firstName = "Aline";
    }
}

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 continue to 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