C# 根据内容设置样式

C# 根据内容设置样式,c#,wpf,combobox,styles,C#,Wpf,Combobox,Styles,我目前正在尝试为combobox中显示为选中的项目编写适当的样式。我这样做的原因是,我无法控制ComboBox如何显示所选项目,例如,在深色背景下,项目仍然显示为黑色 我提出了以下解决方案: <DataTemplate x:Key="MyItem" DataType="ComboBoxItem"> <TextBlock Text="{Binding}" Foreground="White"/> </DataTemplate> <!-- (...

我目前正在尝试为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>

现在,当选择简单的
组合框项目时,它将正确显示在组合框中。另一方面,如果我(例如)显示一个包含某些内容的按钮,作为回报,我会得到文本
System.Windows.Shapes.Rectangle
,这与我想要显示的内容相去甚远

我想为组合框中显示的不同数据类型使用不同的模板-我将能够自定义它们的外观。我怎样才能做到这一点


编辑:

非常清楚地说,我在这里谈论的是选中的(=选中的)组合框项:


(与组合框列表中选定的组合框项目无关)

在我看来,您正在寻找ContentTemplateSelector:


看看这些链接。

好的,这个问题有几个不同的方面。首先,我们可以通过将其添加到
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" />

如果您用这三种类型的项目填充了
组合框
,并使用这些
数据模板
s,那么这些项目将被涂成
红色
、绿色
和蓝色。

我将为所有人保留
内容模板选择器
的解决方案,他们将为同一问题寻求解决方案

  • 将以下类添加到库/应用程序:

    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;
        }
    }
    
  • 定义两个不同的数据模板:

    <DataTemplate x:Key="ComboBoxTextItem">
        <TextBlock Text="{Binding}" Foreground="{DynamicResource {x:Static vs:VsBrushes.WindowTextKey}}" />
    </DataTemplate>
    
    <DataTemplate x:Key="ComboBoxOtherItem">
        <ContentPresenter Content="{Binding}" />
    </DataTemplate>
    

  • 您能否提供一个小示例,说明如何将ContentTemplateSelector嵌入到我的DataTemplate中?您是否查看了链接?我查看了,但是
    ComboBox
    似乎没有
    ContentTemplateSelector
    属性。您的项目将放置在ComboBoxItems中。ComboBox只是提供ComboBoxItems的控件的名称。ComboBoxItem显示实际数据。因此ComboBoxItem确实具有ContentTemplateSelector属性。在这里看一看:当然可以,但我并没有设置列表中显示的项目的样式(实际上,根据类型设置样式要容易得多),而是显示为选中的项目。此项目显示在ContentPresenter中,它是我的组合框模板的一部分。查看我的编辑。你确定你说的是与我说的相同的“选定项”吗?我对我的问题做了一些修改,以表明我在说什么。你是对的,我确实认为你在谈论实际选定的项目。但是,无论数据类型实例显示在哪里,单独的
    DataTemplate
    s都应该仍然有效。
    <DataTemplate x:Key="ComboBoxTextItem">
        <TextBlock Text="{Binding}" Foreground="{DynamicResource {x:Static vs:VsBrushes.WindowTextKey}}" />
    </DataTemplate>
    
    <DataTemplate x:Key="ComboBoxOtherItem">
        <ContentPresenter Content="{Binding}" />
    </DataTemplate>
    
    <Style.Resources>
        <local:ComboBoxSelectionTemplateSelector ContentTemplate="{StaticResource ComboBoxOtherItem}" 
                                                 TextTemplate="{StaticResource ComboBoxTextItem}" x:Key="ContentTemplateSelector" />
    </Style.Resources>
    
    <!-- ... -->
    <ControlTemplate TargetType="ComboBox">
        <Grid>
            <ContentPresenter ContentTemplateSelector="{StaticResource ContentTemplateSelector}"
                              Content="{TemplateBinding ComboBox.SelectionBoxItem}" />
            <!-- Other items -->
            <Popup ... /> <!-- For displaying ComboBox's list -->
        </Grid>