DCSIMG
TreeView DataBinding and The Composite Pattern - David Sackstein's Blog

TreeView DataBinding and The Composite Pattern

In the previous post I demonstrated use of the HierarchicalDataTemplate to style nodes based on the type of the object that they are bound to. That declarative recursion gets you true separation between data and presentation.

In this post, I will show how I made use of the Composite Pattern, INotifyPropertyChanged and BindingSource<T> to implement objects for DataBinding with the TreeView.

In the next post I will show how I used LINQ to XML to read the data from an XML file.

The Composite Pattern

In the example at hand, HierarchicalDataTemplate is able to apply styles recursively because the type with which it is associated has a property which is a collection of objects of types for which a HierarchicalDataTemplate is defined. That collection can then be bound to the ItemsSource property of the template.

This works particularly well when the objects implement the Composite Pattern. Using the pattern, you can construct trees of objects with any hierarchy because all objects can be stored in collections of the base type, Composite.

As the example shows, you can set the HierarchicalDataTemplate’s ItemsSource to the Children property which is a collection of Composite objects and then provide a HierarchicalDataTemplate for the specific type.

Implementing the DataBinding

As you know, in order to get the Source to update the Target in a databinding expression, the Source needs to implement some change notification interface.

One way to do this is to make the Source property into a DependencyProperty. A disadvantage of this approach is that it ties your business layer into the System.Windows namespace, which is rarely a good idea. A more lightweight approach is to implement the INotifyPropertyChanged interface on the Source type.

INotifyPropertyChanged defines one event that you are expected to raise whenever the value of one of the object’s properties changes. The name of the property whose value changed is provided as an argument of the event invocation. It is the responsibility of the class implementor to make sure that for every property (for which databinding should be implemented) a change in value generates the event. (This is usually done in the ‘set’ handler of the property).

We are not done yet, however.

In our example we need to bind nodes of TreeView to a collection. For this we also need a notification when objects are added or removed from the collection.

There are two standard ways to do this.

The first, legacy approach, is to use collections that implement IBindingList. IBindingList has a ListChanged event and is analogous to INotifyPropertyChanged – for collections. This sounds a little complex, but the good news is that you don’t have to implement IBindingList yourself, you can just use the generic BindingList<T> type to represent your collections of T. BindingList is implemented in the System.Component namespace, and is in many ways an IList<T> with an implementation of IBindingList.

The second approach is to use the ObservableCollection<T> class that was introduced by WPF in the System.Collections.ObjectModel namespace. You can read a discussion about the difference between the two approaches here.

In this example, however, I will use the BindingList because it doesnt require the business layer to reference the WPF assembly, WindowsBase.

So, this is the Composite class I defined for use with the TreeView from the previous post:

namespace OrganizationData

{

    abstract public class Composite : INotifyPropertyChanged

    {

        #region Properties

 

        string name;

        public string Name

        {

            get { return name; }

            set

            {

                name = value;

                RaisePropertyChanged("Name");

            }

        }

 

        BindingList<Composite> children;

        public BindingList<Composite> Children

        {

            get { return children; }

            set

            {

                children = value;

                RaisePropertyChanged("Children");

            }

        }

 

        #endregion

 

        #region INotifyPropertyChanged Members

 

        public event PropertyChangedEventHandler PropertyChanged;

 

        protected void RaisePropertyChanged(string propertyName)

        {

            if (PropertyChanged != null)

            {

                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

            }

        }

 

        #endregion

    }

}

And here are few business objects, derived from Composite. A Department has an additional Budget property.

namespace OrganizationData

{

    public class Department : Composite

    {

        #region Properties

 

        double budget;

 

        public double Budget

        {

            get { return budget; }

            set

            {

                budget = value;

                RaisePropertyChanged("Budget");

            }

        }

 

        #endregion

    }

}

and an Employee has a Role property and a Salary property.

namespace OrganizationData

{

    public class Employee : Composite

    {

        #region Properties

 

        string role;

        public string Role

        {

            get { return role; }

            set

            {

                role = value;

                RaisePropertyChanged("Role");

            }

        }

 

        double salary;

        public double Salary

        {

            get { return salary; }

            set

            {

                salary = value;

                RaisePropertyChanged("Salary");

            }

        }

 

        #endregion

    }

}

In the next post I will show how I used LINQ to XML to such objects from an XML file.

Published Friday, June 05, 2009 9:59 PM by David Sackstein

Comments

# LINQ to XML

Friday, June 05, 2009 11:21 PM by David Sackstein's Blog

In this post, I will show how I used LINQ to XML to construct data that complies with the Composite Pattern

# Demonstrating DataBinding with TreeView

Saturday, June 06, 2009 2:08 AM by David Sackstein's Blog

In the previous posts I have shown how I used the Composite Pattern to describe hierarchical data , to

# HierarchicalDataTemplate and TreeView - David Sackstein&#39;s Blog

Pingback from  HierarchicalDataTemplate and TreeView - David Sackstein&#39;s Blog

Leave a Comment

(required) 
(required) 
(optional)
(required) 

Enter the numbers above:
Powered by Community Server (Commercial Edition), by Telligent Systems