Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

WPF Master Pages

0.00/5 (No votes)
8 Jul 2007 1  
One of the really great enhancements in ASP.NET was the introduction of master pages. They help developers to create a consistent layout for the pages in an application. Unfortunatly there is no such concept in WPF. But there is an easy way to build a control similar to an ASP.NET master page.

Screenshot - Page1.png

Introduction

One of the really great enhancements in ASP.NET was the introduction of master pages. They help developers to create a consistent layout for the pages in an application. Unfortunately there is no such concept in WPF and XAML. In the following sample, I would like to show a simple way to build a control in WPF similar to an ASP.NET master page.

Building Master Pages in WPF

My application consists of a Window, which contains a menu and a frame, and three Pages. These pages will be displayed in the frame when a user clicks on the menu.

When I add a new page to my project I can add controls to this page and arrange them the way I like. In my sample I use a Grid to arrange a title and a description on my new page.

<Page x:Class="MasterPages.Page.Page1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Page1"
    >
    <Grid Margin="10">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

       <TextBlock Style="{StaticResource Title}" Grid.Column="0" 
                Grid.Row="0" Text="Page 1" />
       <TextBlock Grid.Column="0" Grid.Row="1" 
                Text="This is the content of Page 1." />
    </Grid>
</Page>

If I want to add a second page with a similar layout to my project without master pages, I would have to repeat the whole code for the grid to arrange title and description on my new page.

An easy way to encapsulate the grid layout is to build a user control for the general layout of a page. Therefore I add a new UserControl to my project. In the codebehind file of my control, I add two dependency properties, one for the title and one for the page content:

public partial class Master : System.Windows.Controls.UserControl
{
    public Master()
    {
        InitializeComponent();
    }

    // Title

    public object Title
    {
        get
        {
            return (object)GetValue(TitleProperty);
        }
        set
        {
            SetValue(TitleProperty, value);
        }
    }

    public static readonly DependencyProperty TitleProperty = 
    DependencyProperty.Register(
        "Title",
        typeof(object),
        typeof(Master),
        new UIPropertyMetadata());

    // PageContent

    public object PageContent
    {
        get
        {
            return (object)GetValue(PageContentProperty);
        }
        set
        {
            SetValue(PageContentProperty, value);
        }
    }

    public static readonly DependencyProperty PageContentProperty = 
    DependencyProperty.Register(
        "PageContent",
        typeof(object),
        typeof(Master),
        new UIPropertyMetadata());
}

Title and PageContent act as a placeholder. In the XAML file of my user control, I can arrange these placeholders:

<UserControl x:Class="MasterPages.App_Master.Master"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:m="clr-namespace:MasterPages.App_Master">
    <Grid Margin="10">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <ContentControl
            Grid.Column="0"
            Grid.Row="0"
            Style="{StaticResource Title}"
            Margin="0 0 0 10"
            Content="{Binding RelativeSource=
        {RelativeSource Mode=FindAncestor, 
        AncestorType={x:Type m:Master}}, Path=Title}" />


        <ContentControl
            Grid.Column="0"
            Grid.Row="1"
            Content="{Binding RelativeSource=
        {RelativeSource Mode=FindAncestor, 
        AncestorType={x:Type m:Master}}, Path=PageContent}" />
    </Grid>
</UserControl>

Now I can use my user control to build pages with a title and a content area. Therefore I have to include the namespace of the user control in the page. Then I can add the user control to the page as the root element. Within the user control I can specify a Title and a PageContent element in XAML. Title and PageContent can contain any other WPF elements:

<Page x:Class="MasterPages.Page.Page1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:m="clr-namespace:MasterPages.App_Master"
    Title="Page1">
    <m:Master>
        <m:Master.Title>
            Page 1
        </m:Master.Title>
        <m:Master.PageContent>
            This is the content of Page 1.
        </m:Master.PageContent>
    </m:Master>
</Page>

Page1 is now a lot easier to build. I do not have to remember for every page that I have to use a Grid with a margin of ten and other details. I simply can set the content for the properties Title and PageContent.

But it is not only possible to add text to the placeholder properties but also to add other WPF controls. In Page2 I add a StackPanel with further controls to the PageContent property:

<Page x:Class="MasterPages.Page.Page2"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:m="clr-namespace:MasterPages.App_Master"
    Title="Page2">
    <m:Master>
        <m:Master.Title>
            Page 2
        </m:Master.Title>
        <m:Master.PageContent>
            <StackPanel>
                <TextBlock Text="Page 2 contains additional elements." />
                <ListBox>
                    <ListBoxItem>Item 1</ListBoxItem>
                    <ListBoxItem>Item 2</ListBoxItem>
                    <ListBoxItem>Item 3</ListBoxItem>
                </ListBox>
            </StackPanel>
        </m:Master.PageContent>
    </m:Master>
</Page>

Screenshot - Page2.png

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here