views:

2520

answers:

3

What I need to accomplish is a ComboBox that shows People. When you expand the drop-down it shows FirstName and LastName, but when you select a person, the value shown at the combobox should be just the person's first name.

I have the following ItemTemplate:

<ComboBox.ItemTemplate>
    <DataTemplate>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding FirstName}" />
            <TextBlock Text=" " />
            <TextBlock Text="{Binding LastName}" />
        </StackPanel>
    </DataTemplate>
</ComboBox.ItemTemplate>

What else should I do to display only the first name when one item is selected?

Thanks!

EDIT

Changed the question slightly: What if I have the person's picture and instead of showing just the first name when a person is selected, I want to show only the picture. In other words, how can I have two separate templates - one for the drop-down and one for the selected item?

+3  A: 

I got it. I just needed to add the following to my ComboBox:

IsEditable="True" IsReadOnly="True" TextSearch.TextPath="FirstName"
Gustavo Cavalcanti
This solves my initial question but I changed it a little bit. How can I display only the picture as opposed to the FirstName when an item is selected?
Gustavo Cavalcanti
Thanks for that, need a simple solution for this.
TheZenker
Love it, EXACTLY what i was looking for!
LnDCobra
+2  A: 

Put a Trigger on the DataTemplate. The trigger should check the IsSelected property (the DataTemplate will need a TargetType set for this to work). If it is selected, you can set the Visibility of your TextBlocks to Collapsed, and set the Visibility of the Image to Visible. Then do the opposite for the case that it is not selected.

Charlie
Thanks. That makes sense, since in a ComboBox only one item is selected. Good idea.
Gustavo Cavalcanti
+6  A: 

Here's the solution:

    <ComboBox>
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <ContentControl x:Name="content" Content="{Binding}" ContentTemplate="{StaticResource ComplexTemplate}"/>
                </StackPanel>
                <DataTemplate.Triggers>
                    <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ComboBoxItem}}" Value="{x:Null}">
                        <Setter TargetName="content" Property="ContentTemplate" Value="{StaticResource SimpleTemplate}"/>
                    </DataTrigger>
                </DataTemplate.Triggers>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>

Basically, you create one more layer of DataTemplate here. ComboBox'es ItemTemplate always stays the same. But the content inside that template adjusts to the condition you are interested in.

The trick to discriminate dropped-down combobox items against selected-area combobox item is that selected-area is not really enclosed in ComboBoxItem object, it's part of ComboBox control itself. So FindAncestor for ComboBoxItem returns null, which we use in the trigger above.

Oleg Mihailik