WPF Expander HeaderTemplates – Don’t Forget The Binding!

Every time I customize an Expander in WPF using a HeaderTemplate, I make a critical mistake. I forget to set the binding for the header. Here’s a contrived example to demonstrate the problem – and the solution.

Here’s what we’re aiming for. A simple Expander with a title and a few lines of text contained within. Of course, a HeaderTemplate is overkill here, but it’s necessary in order to demonstrate the problem.

Let’s start by creating a simple view model for our Expander to bind to:

public class DemoViewModel
{
    public string Title { get; set; }
    public string ContentLine1 { get; set; }
    public string ContentLine2 { get; set; }
    public string ContentLine3 { get; set; }
}

Now create an instance of the view model and set it as the data context for the window:

public partial class MainWindow : Window
{
    public DemoViewModel ViewModel { get; set; }

    public MainWindow()
    {
        InitializeComponent();
        InitializeViewModel();
    }

    private void InitializeViewModel()
    {
        ViewModel = new DemoViewModel
        {
            Title = "Expander Title",
            ContentLine1 = "This is line 1",
            ContentLine2 = "This is line 2",
            ContentLine3 = "This is line 3"
        };
        this.DataContext = ViewModel;
    }
}

Switch to XAML mode and create an Expander with a HeaderTemplate:

<Expander Width="200">
    <Expander.HeaderTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Title}" />
            </StackPanel>
        </DataTemplate>
    </Expander.HeaderTemplate>
    <StackPanel>
        <TextBlock Text="{Binding ContentLine1}" />
        <TextBlock Text="{Binding ContentLine2}" />
        <TextBlock Text="{Binding ContentLine3}" />
    </StackPanel>
</Expander>

When you run this code you’ll notice that the header is blank. The bindings inside the HeaderTemplate don’t bind. I’m no expert, but this seems to be because the data context for the header is not inherited from the data context of the Expander… which seems a little odd to me, but I’m sure there’s a good reason.

The fix is simple enough, just add the attribute Header={Binding} to the Expander:

<Expander Header="{Binding}" Width="200">
...

The bindings inside the HeaderTemplate should now work:

Advertisements
This entry was posted in Reference and tagged , , . Bookmark the permalink.

8 Responses to WPF Expander HeaderTemplates – Don’t Forget The Binding!

  1. xyz says:

    This is really helpful..I too had faced similar issue

  2. Yes, That’s odd to me too, and finally thanks your solution.

  3. I constantly spent my half an hour to read this blog’s posts every day along with a mug of coffee.

  4. sumit says:

    Instead of “Expander Title” can I show dynamic data from my viewmodel, in header title everytime in expander??

  5. Ellen Lux says:

    A great Thank!!
    I understand over read a long time, what I need for costumize my EXPANDER is a controltemplate, but is just not the time for me at the moment..;;(
    You help me go further without frustration. The most Questions in the Web is about align the Header.
    I think the Problem is not this really. If you need Expander.Header, the Design is perfect in Design Time, but you see only the Header-Text (first entry) in Lifetime. (If it is not so (by you..), please a comment for me..:)
    You take me a middle way to understand, so I can go further..
    Greetings from Leipzig
    Ellen

    PS. I’m a native German writer, and over years old.

  6. Rino says:

    Great… Thank you.

  7. martin says:

    thanks. Very helpful!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s