Click here to Skip to main content
11,632,260 members (80,563 online)
Click here to Skip to main content

How to: Use the Master-Detail Pattern with WPF Hierarchical DataTemplate

, 7 Apr 2014 CPOL 13.7K 847 41
Rate this:
Please Sign up or sign in to vote.
This article shows a simple way to implement Master-Detail pattern with hierarchical DataTemplate

Introduction

This article shows a practical & simple way to implement Master-Detail pattern with hierarchical DataTemplate.

Background

Master-Detail is a frequently used pattern in computer science and information systems. Almost every data oriented project is using this pattern. The principle is very simple, showing list of details by selected master item:

We can implement Master-Detail in multiple ways to achieve this pattern, in my opinion the easiest way to do so in WPF is using DataTemplate.

Representing the Hierarchical Data

Every Master-Detail pattern requires a data structure. As an example of a hierarchical data-structure, I’ve chosen to use the following hypothetical Hi-Tech company:

The company is comprised of three departments:

  • Management: CEO, CTO, VP.QA
  • Development: CTO and subordinates on the development team.
  • QA: VP of QA and subordinates on the QA team.

For this example, I've chosen to take the aspect of the departments, i.e. every row in the view is a different department:

Let's look at the classes:

public class Employee
{
    public Employee()
    {
        Subordinates = new List<Employee>();
    }

    public List<Employee> Subordinates { get; set; }

    public string Name
    {
        get;
        set;
    }

    public override string ToString()
    {
        return this.Name;
    }
} 

Each employee includes “subordinates” which is a collection of employees.

public class Department : INotifyPropertyChanged
{
    public Department()
    {
        Employees = new List<Employee>();
    }

    public List<Employee> Employees { get; set; }

    protected int m_EmployeesSelectedIndex = 0;

    public int EmployeesSelectedIndex
    {
        get
        {
            return m_EmployeesSelectedIndex;
        }
        set
        {
            m_EmployeesSelectedIndex = value;
            NotifyPropertyChanged("Subordinates");
        }
    }

    public List<Employee> Subordinates
    {
        get
        {
            List<Employee> res = null;
            if (Employees.Count > 0)
            {
                res = Employees[EmployeesSelectedIndex].Subordinates;
            }

            return res;
        }
    }

    public string Name
    {
        get;
        set;
    }

    public override string ToString()
    {
        return this.Name;
    }

    // This method is called by the Set accessor of each property. 
    // The CallerMemberName attribute that is applied to the optional propertyName 
    // parameter causes the property name of the caller to be substituted as an argument. 
    private void NotifyPropertyChanged(String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
} 

Every department includes a collection of the employees working there.

The Department class also contains the following members:

  1. EmployeesSelectedIndex
  2. Subordinates list
  3. NotifyPropertyChanged mechanism

All of these are used for implementing the Master-Detail Logic, and will be explained in the section "Master-Detail Logic" below.

Presenting the Data (UI):

For the sake of simplicity, we are presenting the data inside an ItemsControl:

<!-- Data rows -->
<ItemsControl ItemsSource="{Binding Items}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal" MinWidth="320">                    
                <TextBlock Width="130" Text="{Binding Name}"/>          
                <ComboBox Width="130" ItemsSource="{Binding Employees}" SelectedIndex="{Binding EmployeesSelectedIndex}" />         
                <ComboBox Width="130" ItemsSource="{Binding Subordinates}" />            
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl> 

So what we are dealing with here is simply a DataTemplate with:

  • TextBlock - For the department name.
  • ComboBox - For the departments’ employees’ names.
  • ComboBox - For the selected employee’s subordinates.

Please Notice: In the code sample attached for download, there are also headers, borders & other simple UI decorations for each data item, but the logic is the same.

It should look like this:

Master-Detail Logic:

We need to connect the selection of a particular employee to that employee’s subordinates list.

That is why the Department class contains:

  1. EmployeesSelectedIndex
  2. Subordinates list
  3. NotifyPropertyChanged mechanism

Let’s see how it works:

About the examples for download:

The examples for download are a bit more complicated:

Master-Detail Simple file also contains:

  • Headers, borders & other simple UI decorations for each data item.
  • Subordinates Selected-Index for default selection of the first index in the Subordinates Combo-Box.
  • Subordinates Is-Enabled for disabling the Subordinates Combo-Box when there are no Items.

Master-Detail Advanced file also contains:

  • all of the above (from the Simple example)
  • Employee-Image & Subordinate-Image

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Shai Vashdi
Chief Technology Officer GalilCS
Israel Israel
My name is Shai Vashdi and I’m the CTO & Co-Founder of GalilCS.
GalilCS provides industrialized, low-cost IT services (ILCS) to corporations around the globe. We specialize in code modernization projects (VB6 to C# WinForms/HTML5, for example) and code refactoring projects.
Most of my work revolves around the management of these projects and the creation of new tools for refactoring code. As a bonus, I also get to lecture about Microsoft programming languages.
For more information, visit GalilCS.

You may also be interested in...

Comments and Discussions

 
QuestionHierarchical Data ? Pin
Master.Man198016-Apr-14 7:46
memberMaster.Man198016-Apr-14 7:46 
AnswerRe: Hierarchical Data ? Pin
Shai Vashdi16-Apr-14 8:40
memberShai Vashdi16-Apr-14 8:40 
GeneralMy vote of 5 Pin
Member 104747568-Apr-14 23:46
memberMember 104747568-Apr-14 23:46 
GeneralMy vote of 3 Pin
yoav bernoli8-Apr-14 3:17
memberyoav bernoli8-Apr-14 3:17 
GeneralRe: My vote of 3 Pin
Shai Vashdi8-Apr-14 3:58
memberShai Vashdi8-Apr-14 3:58 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150728.1 | Last Updated 7 Apr 2014
Article Copyright 2014 by Shai Vashdi
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid