Как использовать другой шаблон для выбранных и раскрывающихся состояний в поле со списком в Silverlight? - PullRequest
6 голосов
/ 07 ноября 2008

Я не могу установить ContentTemplate для ComboBoxItem. Причина, по которой я пытаюсь это сделать, заключается в том, что я хочу, чтобы мои данные отображались в поле со списком 2 раза. Когда поле со списком открыто (меню не работает), я хочу текстовое поле (с именем изображения) и элемент управления изображением под ним. Когда я выбираю элемент, я хочу, чтобы в поле со списком просто отображалось текстовое поле с названием изображения.

Я думал, что смогу добиться этого, изменив ItemTemplate и ItemContainerStyle ComboBox. ItemContainerStyle содержит следующий ContentPresenter:

<ContentPresenter HorizontalAlignment="Left" Margin="{TemplateBinding Padding}" x:Name="contentPresenter" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/>

Итак, я предположил, что я мог бы просто установить ContentTemplate здесь, и он будет работать. Но я не могу заставить его работать:

<DataTemplate x:Key="ComboBoxDataTemplate">
            <Grid>
                <TextBlock Text="{Binding Path='Name'}"/>
            </Grid>
        </DataTemplate>

<DataTemplate x:Key="ComboBoxItemTemplate">
            <StackPanel>
                <TextBlock Text="{Binding Path='Name'}"/>
                <Image Source="{Binding Path='Source'}" Width="64" Height="64"/>
            </StackPanel>
        </DataTemplate>

        <Style x:Key="ComboBoxItemStyle1" TargetType="ComboBoxItem">
...
            <Setter Property="ContentTemplate" Value="{StaticResource ComboBoxItemTemplate}"/>

...

Вот мое поле со списком:

<ComboBox Width="70" Margin="3,0,0,0"
                        ItemsSource="{StaticResource Source}"
                        ItemTemplate="{StaticResource ComboBoxDataTemplate}"
                        ItemContainerStyle="{StaticResource ComboBoxItemStyle1}"
                        />

Единственный способ заставить это работать - удалить ContentPresenter из ItemContainerStyle и заменить его содержимым моего пользовательского шаблона (ComboBoxItemTemplate). Но я не думал, что должен использовать этот подход, поскольку это означает, что ContentPresenter больше не существует (и код в ComboBox может полагаться на его существование).

Любая помощь в отображении поля со списком с другим раскрывающимся списком и выбранным шаблоном будет принята с благодарностью!

Ответы [ 3 ]

5 голосов
/ 14 сентября 2010

ComboBox.ItemTemplate - это просто удобный способ установить ComboBoxItem.ContentTemplate. Таким образом, ваш код выше в основном пытается установить ComboBoxItem.ContentTemplate дважды.

Как указал Джоби, вы можете попробовать использовать только собственный стиль. Вы можете безопасно исключить ContentPresenter, если вы всегда знаете тип контента. ContentPresenter просто позволяет вам использовать DataTemplate для отображения некоторых случайных данных. Но вы можете просто заменить его на TextBlock и изображение. Вы просто теряете возможность указывать шаблон данных.

Проблема с подходом Джоби состоит в том, что выбранный элемент не будет отображать его изображение, даже если он находится в раскрывающемся списке. Действительно выбранный элемент отображается в двух местах (раскрывающийся список и основной текст ComboBox). В одном месте вам нужен один DataTemplate, а в другом - другой DataTemplate.

Лучше всего изменить стиль ComboBox. Вы можете получить стиль по умолчанию от здесь . Существует ContentPresenter с именем «ContentPresenter». Вам необходимо:

  1. Удалить / изменить имя ContentPresenter, поэтому ComboBox не будет автоматически устанавливать свойства Content / ContentTemplate
  2. Свяжите свойство ContentPresenter.Content следующим образом: "{TemplateBinding SelectedObject}"
  3. Установите свойство ContentPresenter.ContentTemplate для своего DataTemplate без изображения
  4. Установите свойство ComboBox.ItemTemplate на DataTemplate с изображением и текстовым блоком, как вы были
  5. Дайте стилю ComboBox явный ключ, например x: Key = "MyComboBoxStyle"
  6. Используйте стиль в вашем ComboBox, например Style = "{StaticResource MyComboBoxStyle}"

Это эффективно игнорирует ComboBoxItem.ContentTemplate при отображении выбранного элемента в теле ComboBox, но использует его при отображении ComboBoxItem в раскрывающемся списке.

0 голосов
/ 21 ноября 2008

DataTemplate в основном предназначен для вашей визуализации данных. Лучше представить всю динамику, связанную с пользовательским интерфейсом, внутри ControlTemplate (элементы управления). Нет потенциальной проблемы, если у вас нет ContentPresenter. Единственная проблема заключается в том, что если вы хотите повторно использовать этот ControlTemplate из какого-либо другого ComboBox. Затем вы можете объявить еще один чистый шаблон управления с ContentPresenter там.

0 голосов
/ 07 ноября 2008

Вы можете достичь этого только с помощью ItemsContainerStyle. Добавьте ваш TextBlock и изображение вместо ContentPresenter. Добавьте VisualStateManager и переключите элемент управления «Видимость изображения» на основе выбранного состояния VSM.

...