Master-Detail View is powerful feature of WPF. For example, It allows you to select product from the left ListBox and view details about the selected product on the right ListBox. Of course, you can create this one in another technology, but in WPF it’s very simple. A few days ago I created suitable database for my sample application. Database contains information about all regions, divisions, cities, districts and streets in the Czech Republic. Look at the schema:

Database Schema

Database is ready and now you must create Window object for our Master-Detail View. Window contains main Grid, that is divided into five columns. Each of them is consisted by Label and ListBox wrapped into DockPanel. Label is used only for information purpose and ListBox contains names of Regions, Divisions, etc..XAML of Window looks like this:

<Window x:Class="MasterDetailView.MainWindow"
    Title="Master - Detail View" Height="400">
    <Grid x:Name="gridMasterDetail">
            <ColumnDefinition Width="200" />
            <ColumnDefinition Width="200" />
            <ColumnDefinition Width="200" />
            <ColumnDefinition Width="200" />
            <ColumnDefinition Width="200" />
        <DockPanel Grid.Column="0">
            <Label DockPanel.Dock="Top">Region</Label>
            <ListBox ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True" DisplayMemberPath="Name"/>
        <DockPanel Grid.Column="1">
            <Label DockPanel.Dock="Top">Division</Label>
            <ListBox ItemsSource="{Binding Path=Divisions}" IsSynchronizedWithCurrentItem="True" DisplayMemberPath="Name" />
        <DockPanel Grid.Column="2">
            <Label DockPanel.Dock="Top">City</Label>
            <ListBox ItemsSource="{Binding Path=Divisions/Cities}" IsSynchronizedWithCurrentItem="True" DisplayMemberPath="Name"/>
        <DockPanel Grid.Column="3">
            <Label DockPanel.Dock="Top">District</Label>
            <ListBox ItemsSource="{Binding Path=Divisions/Cities/Districts}" IsSynchronizedWithCurrentItem="True" DisplayMemberPath="Name" />
        <DockPanel Grid.Column="4">
            <Label DockPanel.Dock="Top">Street</Label>
            <ListBox ItemsSource="{Binding Path=Divisions/Cities/Districts/Streets}" DisplayMemberPath="Name" />

Note: Purpose of each ListBox ItemSource bindings I’ll explain later

So when I choose Region in the first ListBox, I want to see all division of selected Region, then when I choose some Region, I want to see all cities, etc. The first step that I perform is set up DataContext of DataGrid:

public MainWindow()
   AddressesDataContext ctx = new AddressesDataContext();
   gridMasterDetail.DataContext = from c in ctx.Regions
                                  select c;

I create instance of LINQ DataContext and then execute query that returns all Regions. Now is the time for explanation each bindings of all ListBox.

The first ListBox ItemsSource is set only to {Binding}, because DataContext directly contains collection of regions. The second ListBox ItemsSource is set to {Binding Path=Divisions}, because each region has collection of Division called Divisions.The third ListBox ItemsSource is set to {Binding Path=”Divisions/Cities”} – Region has collection called Divisions and each division has collection called Cities. Other ListBox ItemsSource is se to {Binding Path=Divisions/Cities/Districts} – Region –> Divisions –> Cities –> Districts. And the last ListBox ItemsSource is set to {Binding Path=Divisions/Cities/Districts/Streets} – Region –> Divisions –> Cities –> Districts –> Streets. Last thing that You must do is set IsSynchronizedWithCurrentItem property for all ListBox controls to true (except last ListBox, because Street object doesn’t have any collection and there is no reason for synchronizing selected item).

Now the running application looks like that:


It’s very easy, isn’t it?

Download sample application and database