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

Using a different DataTemple when a WPF ComboBox is expanded

0.00/5 (No votes)
17 Dec 2009 1  
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 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