2013-11-22 4 views
0

В настоящее время я пытаюсь написать правильный стиль для элемента, отображаемого как выбранный в combobox. Причина, по которой я это делаю, заключается в том, что у меня нет большого контроля над тем, как ComboBox отображает выбранный элемент и, например, на темном фоне элемент все еще отображается черным.Стилирование в зависимости от содержимого

Я пришел со следующим раствором:

<DataTemplate x:Key="MyItem" DataType="ComboBoxItem"> 
    <TextBlock Text="{Binding}" Foreground="White"/> 
</DataTemplate> 

<!-- (...) --> 

<Style TargetType="{x:Type ComboBox}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate> 

      <!-- ... --> 
      <!-- Displaying currently selected item --> 

       <ContentPresenter Margin="2" IsHitTestVisible="False" 
        VerticalAlignment="Center" HorizontalAlignment="Stretch" 
        Name="ContentSite" 
        ContentTemplate="{StaticResource MyItem}" 
        Content="{TemplateBinding ComboBox.SelectionBoxItem}" /> 

      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

Теперь, когда выбран простой ComboBoxItem, он правильно отображается в ComboBox. С другой стороны, если я - например, - отображает кнопку с некоторым контентом, то взамен получаю текст System.Windows.Shapes.Rectangle, что далеко от того, что я хочу отобразить.

Я хотел бы использовать разные шаблоны для разных типов данных, отображаемых в ComboBox - я смогу настроить их внешний вид. Как я могу это достичь?


Edit:

Чтобы быть совершенно ясно, я говорю о выбранной (=), выбранного ComboBox элемента в этом контексте:

Selected item in combo box

(не о выбранной ComboBox item в списке ComboBox)

ответ

1
+0

Можете ли вы предоставить небольшой пример того, как можно встроить, что ContentTemplateSelector в моей DataTemplate? – Spook

+0

Вы посмотрели ссылки? –

+0

Я сделал, но 'ComboBox', похоже, не имеет свойства ContentTemplateSelector. – Spook

0

Правильно, есть несколько различных аспектов этого вопроса. Во-первых, мы можем избавиться от цвета выбора по умолчанию, добавив это в Resources раздел:

<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent" /> 
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent" /> 
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="White" /> 
<SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="Black" /> 

Эксперимент с этими параметрами, как два из них определяют цвет текста и два набора цвета для фона из выбранный элемент. Фактически, вы можете использовать любые цвета здесь, чтобы обеспечить быстрый способ изменить выбранные цвета элементов ... без необходимости идти на все проблемы, с которыми вы столкнулись. Но для вашего примера давайте просто оставьте их как Transparent.

Хорошо, тогда вам нужно будет по-другому взглянуть на каждый другой тип данных, который появляется в ComboBox ... это также может быть легко достигнуто. Все, что вам нужно сделать, это объявить для каждого типа и не устанавливать x:Key объект, чтобы они были неявно применены. Вот простой пример:

<Window.Resources> 
    <DataTemplate DataType="{x:Type Type1}"> 
     <TextBlock Text="{Binding}" Foreground="Red" /> 
    </DataTemplate> 
    <DataTemplate DataType="{x:Type Type2}"> 
     <TextBlock Text="{Binding}" Foreground="Green" /> 
    </DataTemplate> 
    <DataTemplate DataType="{x:Type Type3}"> 
     <TextBlock Text="{Binding}" Foreground="Blue" /> 
    </DataTemplate> 
</Window.Resources> 

Если вы заселена в ComboBox с элементами этих трех типов с этими DataTemplate с, то элементы будут окрашены в Red, зеленый and Blue`.

+0

Ты уверен, что ты говоришь об одном и том же «выбранном» мне? Я немного изменил свой вопрос, чтобы показать, о чем я говорю. – Spook

+0

Ты Правильно, я думал, что вы говорили о выбранном элементе * actual *. Однако отдельный 'DataTemplate' должен работать везде, где отображается экземпляр типа данных. – Sheridan

0

Я оставлю решение с ContentTemplateSelector для всех, кто будет искать решение по той же проблеме.

  1. Добавьте следующий класс в библиотеку/приложения:

    public class ComboBoxSelectionTemplateSelector : DataTemplateSelector 
    { 
    
        public DataTemplate TextTemplate 
        { 
         get; 
         set; 
        } 
    
        public DataTemplate ContentTemplate 
        { 
         get; 
         set; 
        } 
    
        public override System.Windows.DataTemplate SelectTemplate(object item, DependencyObject container) 
        { 
         if (item is string) 
          return TextTemplate; 
         else 
          return ContentTemplate; 
        } 
    } 
    
  2. Определить два различных DataTemplates:

    <DataTemplate x:Key="ComboBoxTextItem"> 
        <TextBlock Text="{Binding}" Foreground="{DynamicResource {x:Static vs:VsBrushes.WindowTextKey}}" /> 
    </DataTemplate> 
    
    <DataTemplate x:Key="ComboBoxOtherItem"> 
        <ContentPresenter Content="{Binding}" /> 
    </DataTemplate> 
    
  3. Instantiate селектор внутри стиля, который вы хотите использовать его в:

    <Style.Resources> 
        <local:ComboBoxSelectionTemplateSelector ContentTemplate="{StaticResource ComboBoxOtherItem}" 
                  TextTemplate="{StaticResource ComboBoxTextItem}" x:Key="ContentTemplateSelector" /> 
    </Style.Resources> 
    
  4. Используйте его в ContentPresenter:

    <!-- ... --> 
    <ControlTemplate TargetType="ComboBox"> 
        <Grid> 
         <ContentPresenter ContentTemplateSelector="{StaticResource ContentTemplateSelector}" 
              Content="{TemplateBinding ComboBox.SelectionBoxItem}" /> 
         <!-- Other items --> 
         <Popup ... /> <!-- For displaying ComboBox's list --> 
        </Grid> 
    
Смежные вопросы