Pages

Wednesday, June 20, 2012

Hierarchical DataBinding in TreeView using MVVM pattern

I am now going to show the interesting work in MVVM pattern that Hierarchical DataBinding in WPF. Basically we will do the Hierarchical DataBinding for the ItemsControl where Items also will be having the ItemsControl as the base classes.

There are more number of Hierarchical data controls are there in wpf like TreeView and Menu control. But here i am going to show the sample using TreeView.

My TreeView should be looking like this when we ran the application

Document1
     Course1
             Bookno-1
             Bookno-2
Document2
     Course 2
             Book no-1
             Book no-2


public class ViewModelBase :INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(string propname)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propname));
        }
    }
}

Model classes in this application will inherit the ViewModelBase class to notify the property changes to the UI. Whenever the property changes in the Model classes will be notified through the ViewModelBase to the UI.



public class Book : ViewModelBase
{
     private string bookname = string.Empty;

     public string BookName
     {
         get
         {
             return bookname;
         }
         set
         {
             bookname = value;
             OnPropertyChanged("BookName");
         }
     }

     public Book(string bookname)
     {
         BookName = bookname;
     }
}


The same way other classes are ...
public class Department : ViewModelBase
{
    private List<Course> courses;

    public Department(string depname)
    {
        DepartmentName = depname;
        Courses = new List<Course>()
        {
            new Course("Course1"),
            new Course("Course2")
        };
    }

    public List<Course> Courses
    {
        get
        {
            return courses;
        }
        set
        {
            courses = value;
            OnPropertyChanged("Courses");
        }
    }

    public string DepartmentName
    {
        get;
        set;
    }
}

public class Course :ViewModelBase
{
    private List<Book> books;

    public Course(string coursename)
    {
        CourseName = coursename;
        Books = new List<Book>()
        {
            new Book("JJJJ"),
            new Book("KKKK"),
            new Book("OOOOO")
        };
    }

    public List<Book> Books
    {
        get
        {
            return books;
        }
        set
        {
            books = value;
            OnPropertyChanged("Books");
        }
    }

    public string CourseName
    {
        get;
        set;
    }
}

Finally the DataContext of the TreeView will be TreeViewModel which will be having the Items of the TreeView which is going to be bound.


public class TreeViewModel :ViewModelBase
{
    private List<Department> departments;

    public TreeViewModel()
    {
        Departments = new List<Department>()
        {
            new Department("Department1"),
            new Department("Department2")
        };
    }

    public List<Department> Departments
    {
        get
        {
            return departments;
        }
        set
        {
            departments = value;
            OnPropertyChanged("Departments");
        }
    }
}

The above ViewModel class will be set as a DataContext for TreeView and finally it will display the Hierarchical items based on the below xaml code.


<Window x:Class="TestApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:this="clr-namespace:TestApp"
        Title="MainWindow" Height="350" Width="525">

    <Window.DataContext>
        <this:TreeViewModel />
    </Window.DataContext>

    <Window.Resources>
        <HierarchicalDataTemplate ItemsSource="{Binding Courses}" DataType="{x:Type this:Department}">
            <Label Content="{Binding DepartmentName}"/>
        </HierarchicalDataTemplate>

        <HierarchicalDataTemplate ItemsSource="{Binding Books}" DataType="{x:Type this:Course}">
            <Label Content="{Binding CourseName}"/>
        </HierarchicalDataTemplate>

        <DataTemplate DataType="{x:Type this:Book}">
            <Label Content="{Binding BookName}"/>
        </DataTemplate>

    </Window.Resources>

    <Grid>
        <TreeView ItemsSource="{Binding Departments}">

        </TreeView>
    </Grid>
</Window>

The HierarchicalDataTemplate has the ItemsSource property to bind the sub level of items to the VisualTree.. It will be helpful to bind 'n' level of sub items into the nested level...


You can find the solution in the below link.