如何在WPF ComboBox中显示下拉列表值/所选项的不同值?

Mar*_*rek 13 wpf binding combobox wpf-controls

我有一个WPF组合框绑定到具有长描述的项目列表.

绑定到ComboBox的类型具有短和长描述作为属性.目前,我对完整描述具有约束力.

comboBox.DisplayMemberPath = "FullDescription";
Run Code Online (Sandbox Code Playgroud)

如何确保在选择项目并将其显示为组合框中的单个项目时,它将显示为ShortDescription属性值,同时显示下拉列表FullDescription

Fre*_*lad 18

更新2011-11-14

我最近又遇到了同样的要求,我对下面发布的解决方案不太满意.这是一种更好的方法来获得相同的行为,而无需重新模板化ComboBoxItem.它使用了DataTemplateSelector

首先,指定常规DataTemplate,下拉DataTemplateComboBoxItemTemplateSelector资源ComboBox.然后引用ComboBoxItemTemplateSelectoras作为DynamicResourceforItemTemplateSelector

<ComboBox ...
          ItemTemplateSelector="{DynamicResource itemTemplateSelector}">
    <ComboBox.Resources>
        <DataTemplate x:Key="selectedTemplate">
            <TextBlock Text="{Binding Path=ShortDescription}"/>
        </DataTemplate>
        <DataTemplate x:Key="dropDownTemplate">
            <TextBlock Text="{Binding Path=FullDescription}"/>
        </DataTemplate>
        <local:ComboBoxItemTemplateSelector
            x:Key="itemTemplateSelector"
            SelectedTemplate="{StaticResource selectedTemplate}"
            DropDownTemplate="{StaticResource dropDownTemplate}"/>
    </ComboBox.Resources>
</ComboBox>
Run Code Online (Sandbox Code Playgroud)

ComboBoxItemTemplateSelector检查容器是否是a的子项ComboBoxItem,如果是,则我们正在处理下拉项,否则它是该项中的项ComboBox.

public class ComboBoxItemTemplateSelector : DataTemplateSelector
{
    public DataTemplate DropDownTemplate
    {
        get;
        set;
    }
    public DataTemplate SelectedTemplate
    {
        get;
        set;
    }
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        ComboBoxItem comboBoxItem = VisualTreeHelpers.GetVisualParent<ComboBoxItem>(container);
        if (comboBoxItem != null)
        {
            return DropDownTemplate;
        }
        return SelectedTemplate;
    }
}
Run Code Online (Sandbox Code Playgroud)

GetVisualParent

public static T GetVisualParent<T>(object childObject) where T : Visual
{
    DependencyObject child = childObject as DependencyObject;
    while ((child != null) && !(child is T))
    {
        child = VisualTreeHelper.GetParent(child);
    }
    return child as T;
}
Run Code Online (Sandbox Code Playgroud)

旧解决方案,需要重新模板化 ComboBoxItem

<SolidColorBrush x:Key="SelectedBackgroundBrush" Color="#DDD" />
<SolidColorBrush x:Key="DisabledForegroundBrush" Color="#888" />

<ControlTemplate x:Key="FullDescriptionTemplate" TargetType="ComboBoxItem">
    <Border Name="Border" Padding="2" SnapsToDevicePixels="true">
        <StackPanel>
            <TextBlock Text="{Binding Path=FullDescription}"/>
        </StackPanel>
    </Border>
    <ControlTemplate.Triggers>
        <Trigger Property="IsHighlighted" Value="true">
            <Setter TargetName="Border" Property="Background" Value="{StaticResource SelectedBackgroundBrush}"/>
        </Trigger>
        <Trigger Property="IsEnabled" Value="false">
            <Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

<ComboBox Name="c_comboBox" ItemsSource="{Binding}">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=ShortDescription}"/>
        </DataTemplate>
    </ComboBox.ItemTemplate>
    <ComboBox.ItemContainerStyle>
        <Style TargetType="{x:Type ComboBoxItem}">
            <Setter Property="Template" Value="{StaticResource FullDescriptionTemplate}" />
        </Style>
    </ComboBox.ItemContainerStyle>
</ComboBox>
Run Code Online (Sandbox Code Playgroud)

这导致以下行为

替代文字

  • 你见过[这种方法](http://stackoverflow.com/a/8279344/546730)? (2认同)
  • 所选选项显示不正确。而是显示完全限定的类属性名称(根据新解决方案) (2认同)