Skip to main content

Master-Detail Pattern

  • 5 minutes to read

The DevExpress Master-Detail Pattern represents a navigation control that consists of a master pane and a details pane. Selecting an item in the master pane updates the content in the details pane.

Master-Detail Pattern

To implement the Master-Detail Pattern in your application, use the MasterDetailPageContent control. To specify the master pane content, use the MasterDetailPageContent.MasterPane property. The details pane content is set using the MasterDetailPageContent.Content property (in XAML, set the content directly between the MasterDetailPageContent start and end tags).

Display Modes

The Master-Detail Pattern supports two display modes:

  • Side by side - both the master and detail panes are shown simultaneously.
  • Stacked - the master pane takes all the available space. When a selection is made, the detail pane gets all the available space.

The MasterDetailPageContent.ViewState property specifies the current display mode.

Adaptive Layout

The Master-Detail Pattern is able to automatically change its display mode based on its current width. This behavior is regulated by the MasterDetailPageContent.EnableAdaptiveLayout property.

The MasterDetailPageContent.StackedStateThreshold property specifies the width, in pixels, at which the Stacked display mode is automatically enabled.

Example

This example illustrates how to create a basic application that uses the Master-Detail Pattern based on the MVVM design pattern.

<Page xmlns:Layout="using:DevExpress.UI.Xaml.Layout" 
    x:Class="Master_Detail_Pattern_MVVM.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Master_Detail_Pattern_MVVM"
    xmlns:mvvmui="using:DevExpress.Mvvm.UI"
    xmlns:Interactivity="using:DevExpress.Mvvm.UI.Interactivity"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <Page.DataContext>
        <local:ViewModel />
    </Page.DataContext>
    <Layout:MasterDetailPageContent Name="MasterDetailPageContent"
                                    EnableSplitter="True"
                                    ThresholdMode="Content" StackedStateThreshold="400" >
        <Layout:MasterDetailPageContent.MasterPane>
            <ListView ItemsSource="{Binding Source}"
                      IsItemClickEnabled="True"
                      SelectedItem="{Binding SelectedEmployee, Mode=TwoWay}"
                      >
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="{Binding FirstName}" Grid.Column="1" FontSize="18" Margin="10,10,0,0" FontFamily="Segoe UI" />
                            <TextBlock Text="{Binding LastName}" Grid.Column="1" FontSize="18" Margin="10,10,0,0" FontFamily="Segoe UI" />
                        </StackPanel>
                    </DataTemplate>
                </ListView.ItemTemplate>
                <Interactivity:Interaction.Behaviors>
                    <mvvmui:EventToCommand EventName="ItemClick" Command="{Binding ElementName=MasterDetailPageContent, Path=ShowContentPaneCommand}" />
                </Interactivity:Interaction.Behaviors>
            </ListView>
        </Layout:MasterDetailPageContent.MasterPane>
        <Grid Padding="10,10,10,0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <TextBlock Text="Country: " FontSize="18" Margin="10,10,0,0" FontFamily="Segoe UI" />
            <TextBlock Text="{Binding SelectedEmployee.Country, Mode=TwoWay}" Grid.Column="1" FontSize="18" Margin="10,10,0,0" FontFamily="Segoe UI" />
            <TextBlock Text="City: " Grid.Row="1" FontSize="18" Margin="10,10,0,0" FontFamily="Segoe UI" />
            <TextBlock Text="{Binding SelectedEmployee.City, Mode=TwoWay}" Grid.Column="1" Grid.Row="1" FontSize="18" Margin="10,10,0,0" FontFamily="Segoe UI" />
            <TextBlock Text="Address: " Grid.Row="2" FontSize="18" Margin="10,10,0,0" FontFamily="Segoe UI" />
            <TextBlock Text="{Binding SelectedEmployee.Address, Mode=TwoWay}" Grid.Column="1" Grid.Row="2" FontSize="18" Margin="10,10,0,0" FontFamily="Segoe UI" />
            <TextBlock Text="Job Title: " Grid.Row="3" FontSize="18" Margin="10,10,0,0" FontFamily="Segoe UI" />
            <TextBlock Text="{Binding SelectedEmployee.JobTitle, Mode=TwoWay}" Grid.Column="1" Grid.Row="3" FontSize="18" Margin="10,10,0,0" FontFamily="Segoe UI" />
            <TextBlock Text="Phone: " Grid.Row="4" FontSize="18" Margin="10,10,0,0" FontFamily="Segoe UI" />
            <TextBlock Text="{Binding SelectedEmployee.Phone, Mode=TwoWay}" Grid.Column="1" Grid.Row="4" FontSize="18" Margin="10,10,0,0" FontFamily="Segoe UI" />
        </Grid>
    </Layout:MasterDetailPageContent>
</Page>
using DevExpress.Mvvm;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Windows.UI.Xaml.Controls;

namespace Master_Detail_Pattern_MVVM {
    public class ViewModel : ViewModelBase {
        public List<Employee> Source {
            get { return GetProperty<List<Employee>>(); }
            set { SetProperty(value); }
        }
        public Employee SelectedEmployee {
            get { return GetProperty<Employee>(); }
            set { SetProperty(value); }
        }

        public ViewModel() {
            Source = EmployeeData.DataSource;
            SelectedEmployee = Source[0];
        }
    }
    public class Employee {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Country { get; set; }
        public string City { get; set; }
        public string Address { get; set; }
        public string JobTitle { get; set; }
        public string Phone { get; set; }
    }
    public class EmployeeData : List<Employee> {
        public static List<Employee> DataSource {
            get {
                List<Employee> list = new List<Employee>();
                list.Add(new Employee() {
                    FirstName = "Nathan",
                    LastName = "White",
                    Country = "Spain",
                    City = "Madrid",
                    Address = "90 7th Street",
                    JobTitle = "Sales Manager",
                    Phone = "(417) 166-3268"
                });
                list.Add(new Employee() {
                    FirstName = "Sandra",
                    LastName = "Oldman",
                    Country = "United States",
                    City = "LA",
                    Address = "3687 Mohawk Street",
                    JobTitle = "Marketing Manager",
                    Phone = "(918) 161-3649"
                });
                list.Add(new Employee() {
                    FirstName = "Andrea",
                    LastName = "Deville",
                    Country = "United Kingdom",
                    City = "London",
                    Address = "14 Garrett Hill",
                    JobTitle = "Accountant",
                    Phone = "(303) 718-1654"
                });
                list.Add(new Employee() {
                    FirstName = "George",
                    LastName = "Holloway",
                    Country = "Canada",
                    City = "Ottawa",
                    Address = "23 Tsawassen Blvd.",
                    JobTitle = "Accounts Manager",
                    Phone = "(720) 971-3927"
                });
                list.Add(new Employee() {
                    FirstName = "Barbara",
                    LastName = "Chinavare",
                    Country = "Hungary",
                    City = "Budapest",
                    Address = "6688 Alhambra Ave",
                    JobTitle = "Tool Designer",
                    Phone = "(360) 186-4982"
                });
                return list;
            }
        }
    }
}