Click here to Skip to main content
Click here to Skip to main content

Using a different DataTemple when a WPF ComboBox is expanded

, 17 Dec 2009
Rate this:
Please Sign up or sign in to vote.
Demonstrates overriding the DataTemplateSelector.SelectTemplate method.

ComboBoxExample

Introduction

This is a WPF combobox that displays one line when closed and multiple lines when expanded.

Using the Code

The first thing I did was create the data templates that control how the address is going be displayed. When it's collapsed, I just wanted to show the AddressName and AddressType on one line:

<DataTemplate x:Key="AddressComboCollapsed" >
    <StackPanel Width="150" HorizontalAlignment="Stretch" >
        <DockPanel HorizontalAlignment="Stretch">
            <TextBlock Text="{Binding Path=AddressName}" 
                       DockPanel.Dock="Left" 
            />
            <TextBlock Text="{Binding Path=AddressType}" 
                       DockPanel.Dock="Right"
                       HorizontalAlignment="Right"
            />
        </DockPanel>
    </StackPanel>
</DataTemplate>

When it's expanded, I want to show the whole address and suppress AddressLine2 if it's blank:

<DataTemplate x:Key="AddressComboExpanded" >
    <GroupBox BorderThickness = "1"
              Margin = "0,0,0,3"
              Width = "Auto "
              HorizontalAlignment = "Stretch"
              Header = "{Binding Path=AddressType}">
        <StackPanel Margin="3" 
                    HorizontalAlignment="Stretch"
                    MinWidth="250">
                <TextBlock Text = "{Binding Path=AddressName}"/>

            <TextBlock Text = "{Binding Path=AddressLine1}"
                       Name = "tbAddr1"
            />
            <TextBlock Text = "{Binding Path=AddressLine2}"
                       Name = "tbAddr2"
            />

            <!-- City, State, and ZIP display -->
            <StackPanel Orientation = "Horizontal">
                <TextBlock Text = "{Binding Path=City}" />
                <TextBlock Text="," Padding="0,0,5,0"/>
                <!-- Put a comma between city and state -->

                <TextBlock Text = "{Binding Path=State}" Padding="0,0,5,0" />
                <TextBlock Text = "{Binding Path=PostalCode}" />
            </StackPanel>
        </StackPanel>
    </GroupBox>

    <DataTemplate.Triggers>
        <!--If the "AddressLine2" portion of the address is blank, then
            HIDE it (no need to display an extra blank line)
            
            This only works is AddressLine2 = "", not if it's null
        -->
        <DataTrigger Binding = "{Binding Path=AddressLine2}" Value = "">
            <Setter TargetName = "tbAddr2" 
                    Property = "Visibility" 
                    Value = "Collapsed"
            />
        </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>

The step was to create a AddressTemplateSelector class that inherits from System.Windows.Controls.DataTemplateSelector.DataTemplateSelector, and override the SelectTemplate method.

public class AddressTemplateSelector : System.Windows.Controls.DataTemplateSelector
{
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        ContentPresenter presenter = (ContentPresenter)container;

        if (presenter.TemplatedParent is ComboBox)
        {
            return (DataTemplate)presenter.FindResource("AddressComboCollapsed");
        }
        else // Templated parent is ComboBoxItem
        {
            return (DataTemplate)presenter.FindResource("AddressComboExpanded");
        }
    }
}

After that, it's just a matter of importing the namespace of the DataTemplateSelector into the Window, merging the Resource Dictionary that contains the DataTemplates, and setting the ItemTemplateSelector of the ComboBox.

<ComboBox Height="30" Width="200"
            ItemsSource="{Binding Path=Addresses}">
    <ComboBox.ItemTemplateSelector>
        <dt:AddressTemplateSelector/>
    </ComboBox.ItemTemplateSelector>
</ComboBox>

Points of Interest

If you look closely at the templates, you'll notice that the expanded template is wider than both the combobox and the collapsed template. This allows you to have the list be wider than the original combobox. That'll be a nice feature when I move on to the state selection combo (display only StateCode, but show StateCode + StateName when expanded).

License

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

About the Author

Jeremy Hutchinson
Software Developer Winxnet
United States United States
No Biography provided
Follow on   Twitter   Google+   LinkedIn

Comments and Discussions

 
QuestionPreload combo selected value Pinmemberalag2020-Aug-12 6:38 
GeneralMy vote of 5 Pinmembertwf195616-Feb-12 10:51 
this is excellent info!
really saved me some time!
GeneralMy vote of 5 PinmemberJohn Adams22-Oct-10 5:45 
Generalgood article, thx PinmemberJacky.ShuaiWu27-May-10 19:59 
GeneralThank you. Pinmemberramfish22-Dec-09 10:50 

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 | Mobile
Web02 | 2.8.140721.1 | Last Updated 17 Dec 2009
Article Copyright 2009 by Jeremy Hutchinson
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid