Подтвердить что ты не робот

Различные шаблоны для элементов в раскрывающемся списке ComboBox и для выбранного элемента

У меня есть ComboBox с довольно сложным шаблоном для отдельных элементов, который включает в себя два изображения и несколько строк текста:

enter image description here

Однако выбранный элемент в ComboBox сам не отображается правильно, потому что вертикальное пространство слишком ограничено (я не могу сделать его выше, потому что он является частью ToolBar).

Как я могу заставить ComboBox использовать другой шаблон для элемента, который отображается в самом ComboBox? (представление по умолчанию ToString будет просто отлично)

Спасибо!

4b9b3361

Ответ 1

Выбранный элемент (в самом 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 не найден. Существуют различные варианты обхода этого: один из них является настраиваемым преобразователем значений, возвращает true или false в зависимости от того, существует ли предок (ручное перемещение дерева).)

Ответ 2

Я искал стандартную (а не хакерскую и без привязки ошибок) решение этой проблемы. И я нашел здесь: используя 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>