ComboBox的下拉列表中的项目和所选项目的不同模板

时间:2011-11-26 14:30:02

标签: wpf xaml datatemplate

我有ComboBox具有相当复杂的单个项目模板,其中包括两个图像和几行文字:

enter image description here

但是,ComboBox本身中的所选项目无法正确显示,因为垂直空间太有限(我无法使其更高,因为它是ToolBar的一部分{1}})。

如何让ComboBox为ComboBox本身显示的项目使用不同的模板?(默认的ToString表示会很好)< / p>

谢谢!

2 个答案:

答案 0 :(得分:27)

所选项目(在ComboBox本身,而非下拉列表中)不在ComboBoxItem内,因此您可以执行以下操作:

<ComboBox.ItemTemplate>
    <DataTemplate>
        <ContentControl Content="{Binding}">
            <ContentControl.Style>
                <Style TargetType="{x:Type ContentControl}">
                    <!-- Complex default template -->
                    <Setter Property="ContentTemplate">
                        <Setter.Value>
                            <DataTemplate>
                                <Image Source="{Binding XPath=media:thumbnail/@url}" Width="100" Height="100" />
                            </DataTemplate>
                        </Setter.Value>
                    </Setter>
                    <Style.Triggers>
                        <!-- Simple selection box template -->
                        <DataTrigger
                                Binding="{Binding RelativeSource={RelativeSource AncestorType=ComboBoxItem}}"
                                Value="{x:Null}">
                            <Setter Property="ContentTemplate">
                                <Setter.Value>
                                    <DataTemplate>
                                        <TextBlock Text="{Binding XPath=title}" />
                                    </DataTemplate>
                                </Setter.Value>
                            </Setter>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ContentControl.Style>
        </ContentControl>
    </DataTemplate>
</ComboBox.ItemTemplate>

编辑:请注意,选择框中的绑定会抛出错误,因为找不到RelativeSource。有各种规避这个的选项,一个是自定义值转换器返回truefalse,具体取决于祖先是否存在(手动树行走)。)

答案 1 :(得分:7)

我正在搜索此问题的标准(不是 hacky 且没有绑定错误)解决方案。我发现它here:使用DataTemplateSelector

@H.B. answer的想法相同:只要在可视树中有ComboBoxItem作为父级,就会检查。

public class ComboBoxItemTemplateSelector : DataTemplateSelector
{
    public DataTemplate SelectedTemplate { get; set; }
    public DataTemplate DropDownTemplate { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        while (container != null)
        {
            container = VisualTreeHelper.GetParent(container);
            if (container is ComboBoxItem)
                return DropDownTemplate;
        }
        return SelectedTemplate;
    }
}

用法:

<ComboBox.ItemTemplateSelector>
    <local:ComboBoxItemTemplateSelector>
        <local:ComboBoxItemTemplateSelector.SelectedTemplate>
            <DataTemplate>
                ... simple template for selected item
            </DataTemplate>
        </local:ComboBoxItemTemplateSelector.SelectedTemplate>
        <local:ComboBoxItemTemplateSelector.DropDownTemplate>
            <DataTemplate>
                ... complex template used by dropdown items
            </DataTemplate>
        </local:ComboBoxItemTemplateSelector.DropDownTemplate>
    </local:ComboBoxItemTemplateSelector>
</ComboBox.ItemTemplateSelector>