如何有条件地仅设置ComboBox所选项目中的文本样式?

时间:2021-11-15 19:59:55

I have a situation where I need to style the selected item in a ComboBox differently (make the text bold) when it is one of all except one value. For example, in the drop-down box labelled "What is your favourite primary colour?" I would have four options: No Preference, Red, Green, and Blue. The ComboBox items are just text with default styling, no images or anything else fancy, and are C# classes, not wrapped in ComboBoxItems.

我有一种情况,我需要以不同的方式对ComboBox中的所选项进行样式设置(使文本变为粗体),除非是一个值。例如,在标有“您最喜欢的原色是什么?”的下拉框中。我有四种选择:无偏好,红色,绿色和蓝色。 ComboBox项只是具有默认样式的文本,没有图像或其他任何花哨的东西,而且是C#类,不包含在ComboBoxItems中。

When the user specifies a preference from the list, I want to highlight that choice by setting the text of the selected item in the collapsed list to be bold. If the user chooses No Preference, the font weight should remain normal.

当用户从列表中指定首选项时,我想通过将折叠列表中所选项目的文本设置为粗体来突出显示该选项。如果用户选择No Preference,则字体粗细应保持正常。

I have achieved a 90% solution by setting the FontWeight property on the ComboBox to Bold in a Style with a DataTrigger defined as SelectedItem != No Preference. However, this styles all items in the ComboBox's list of items, including all those in the drop-down list. I would like those items to always be displayed with a normal font weight.

我已经通过将ComboBox上的FontWeight属性设置为样式中的Bold来实现90%的解决方案,其中DataTrigger定义为SelectedItem!= No Preference。但是,这会对ComboBox项目列表中的所有项目进行样式设置,包括下拉列表中的所有项目。我希望这些项目始终以正常的字体粗细显示。

Is this possible?

这可能吗?

Edit

编辑

I have been trying @crazyar*'s method of styling the ComboBoxItem with a MultiTrigger. The style definition is:

我一直在尝试@ crazyar*用MultiTrigger设置ComboBoxItem样式的方法。样式定义是:

<Style x:Key="SelectedItemStyle">
    <Setter Property="ComboBoxItem.FontWeight" Value="Normal" />
    <Style.Triggers>
        <MultiTrigger>
            <MultiTrigger.Conditions>
                <Condition Property="ComboBoxItem.IsSelected" Value="True" />
                <Condition Binding="{Binding IsNoPreferenceSelected,Mode=OneWay}" Value="False" />
            </MultiTrigger.Conditions>
            <Setter Property="ComboBoxItem.FontWeight" Value="Bold" />
        </MultiTrigger>
    </Style.Triggers>
</Style>

and it is applied to a ComboBox in the following DataTemplate:

它应用于以下DataTemplate中的ComboBox:

<DataTemplate x:Key="PrimaryColoursTemplate" DataType="{x:Type ViewModels:PrimaryColoursViewModel}">
    <ComboBox ItemsSource="{Binding PrimaryColours}" SelectedItem="{Binding SelectedPrimaryColour}"
              ItemContainerStyle="{StaticResource SelectedItemStyle}" />
</DataTemplate>

Unfortunately, this kills WPF:

不幸的是,这会杀死WPF:

System.Windows.Data Error: 8 : Cannot save value from target back to source. BindingExpression:Path=IsDropDownOpen; DataItem='ComboBox' (Name=''); target element is 'ToggleButton' (Name=''); target property is 'IsChecked' (type 'Nullable`1') InvalidOperationException:'System.InvalidOperationException: Must have non-null value for 'Property'.

The application dies with a NullReferenceException, which is thrown after the InvalidOperationException above (or perhaps leads to it, I can't decipher the output). The only thing I can think of that might be causing this is resolving the property in the binding in my second MultiTrigger condition, but I don't get any binding errors at all. Here's the top of the stack trace in case that helps too:

应用程序死于NullReferenceException,它在上面的InvalidOperationException之后抛出(或者可能导致它,我无法解密输出)。我唯一可以想到的可能是导致这是在我的第二个MultiTrigger条件中解析绑定中的属性,但我根本没有得到任何绑定错误。这是堆栈跟踪的顶部,如果有帮助的话:

InvalidOperationException:'System.InvalidOperationException: Must have non-null value for 'Property'.
   at System.Windows.Condition.Seal(ValueLookupType type)
   at System.Windows.ConditionCollection.Seal(ValueLookupType type)
   at System.Windows.MultiTrigger.Seal()
   at System.Windows.TriggerCollection.Seal()
   at System.Windows.Style.Seal()
   at System.Windows.StyleHelper.UpdateStyleCache(FrameworkElement fe, FrameworkContentElement fce, Style oldStyle, Style newStyle, Style& styleCache)
   at System.Windows.FrameworkElement.OnStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
   at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
   at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
   at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
   at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
   at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
   at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
   at System.Windows.Controls.ItemsControl.ApplyItemContainerStyle(DependencyObject container, Object item)

3 个解决方案

#1


5  

There is no need to get into anything as despicable as owner-draw-- we are talking about WPF here, not WinForms. In WinForms, your only solution was to write more code. In WPF, we can solve this problem with a few very simple custom templates. For this example, I used Kaxaml, a free light-weight XAML editor. No code-behind was required. Kaxaml comes packed with a bunch of "starter" styles called Simple Styles. I used the ComboBox Simple Style and made modifications from that. So although this looks like a lot of XAML, I really just started with the boilerplate one and added a couple lines.

没有必要像业主那样进入任何卑鄙的东西 - 我们在这里讨论的是WPF,而不是WinForms。在WinForms中,您唯一的解决方案是编写更多代码。在WPF中,我们可以使用一些非常简单的自定义模板来解决这个问题。在这个例子中,我使用了Kaxaml,一个免费的轻量级XAML编辑器。不需要代码隐藏。 Kaxaml包含了一系列名为Simple Styles的“入门”样式。我使用了ComboBox Simple Style并对其进行了修改。因此,虽然这看起来像很多XAML,但我真的只是从样板文件开始,并添加了几行。

You can probably think of more elegant ways of triggering the font weight change; I used SelectedIndex.

您可以想到更优雅的方式来触发字体重量变化;我使用了SelectedIndex。

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
   <Page.Resources>
      <DataTemplate x:Key="SelectionBoxTextTemplate">
         <TextBlock FontWeight="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ComboBox}}, Path=FontWeight}" Text="{Binding}"/>
      </DataTemplate>
      <ControlTemplate x:Key="ComboBoxToggleButton" TargetType="{x:Type ToggleButton}">
         <Grid>
            <Grid.ColumnDefinitions>
               <ColumnDefinition/>
               <ColumnDefinition Width="20"/>
            </Grid.ColumnDefinitions>
            <Border
               x:Name="Border"
               Grid.ColumnSpan="2"
               Background="#C0C0C0"
               BorderBrush="#404040"
               BorderThickness="1"
               CornerRadius="2"/>
            <Border
               Grid.Column="0"
               Margin="1"
               Background="#FFFFFF"
               BorderBrush="#404040"
               BorderThickness="0,0,1,0"
               CornerRadius="2,0,0,2"/>
            <Path
               x:Name="Arrow"
               Grid.Column="1"
               HorizontalAlignment="Center"
               VerticalAlignment="Center"
               Data="M 0 0 L 4 4 L 8 0 Z"
               Fill="#404040"/>
         </Grid>
         <ControlTemplate.Triggers>
            <Trigger Property="ToggleButton.IsMouseOver" Value="true">
               <Setter TargetName="Border" Property="Background" Value="#808080"/>
            </Trigger>
            <Trigger Property="ToggleButton.IsChecked" Value="true">
               <Setter TargetName="Border" Property="Background" Value="#E0E0E0"/>
            </Trigger>
            <Trigger Property="IsEnabled" Value="False">
               <Setter TargetName="Border" Property="Background" Value="#EEEEEE"/>
               <Setter TargetName="Border" Property="BorderBrush" Value="#AAAAAA"/>
               <Setter Property="Foreground" Value="#888888"/>
               <Setter TargetName="Arrow" Property="Fill" Value="#888888"/>
            </Trigger>
         </ControlTemplate.Triggers>
      </ControlTemplate>
      <Style x:Key="{x:Type ComboBox}" TargetType="{x:Type ComboBox}">
         <Setter Property="SnapsToDevicePixels" Value="true"/>
         <Setter Property="OverridesDefaultStyle" Value="true"/>
         <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
         <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
         <Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
         <Setter Property="MinWidth" Value="120"/>
         <Setter Property="MinHeight" Value="20"/>
         <Setter Property="Template">
            <Setter.Value>
               <ControlTemplate TargetType="{x:Type ComboBox}">
                  <Grid>
                     <ToggleButton
                        Name="ToggleButton"
                        Grid.Column="2"
                        ClickMode="Press"
                        Focusable="false"
                        IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
                        Template="{StaticResource ComboBoxToggleButton}">
                     </ToggleButton>
                     <ContentPresenter
                        Name="ContentSite"
                        HorizontalAlignment="Left"
                        Margin="3,3,23,3"
                        VerticalAlignment="Center"
                        Content="{TemplateBinding SelectionBoxItem}"
                        ContentTemplate="{StaticResource SelectionBoxTextTemplate}"
                        ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
                        IsHitTestVisible="False"/>
                     <TextBox
                        x:Name="PART_EditableTextBox"
                        HorizontalAlignment="Left"
                        Margin="3,3,23,3"
                        VerticalAlignment="Center"
                        Background="Transparent"
                        Focusable="False"
                        IsReadOnly="{TemplateBinding IsReadOnly}"
                        Style="{x:Null}"
                        Visibility="Hidden"/>
                     <Popup
                        Name="Popup"
                        AllowsTransparency="True"
                        Focusable="False"
                        IsOpen="{TemplateBinding IsDropDownOpen}"
                        Placement="Bottom"
                        PopupAnimation="Slide">
                        <Grid
                           Name="DropDown"
                           MaxHeight="{TemplateBinding MaxDropDownHeight}"
                           MinWidth="{TemplateBinding ActualWidth}"
                           SnapsToDevicePixels="True">
                           <Border
                              x:Name="DropDownBorder"
                              Background="#FFFFFF"
                              BorderBrush="#888888"
                              BorderThickness="1"/>
                           <ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
                              <StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained"/>
                           </ScrollViewer>
                        </Grid>
                     </Popup>
                  </Grid>
                  <ControlTemplate.Triggers>
                     <Trigger Property="HasItems" Value="false">
                        <Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/>
                     </Trigger>
                     <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Foreground" Value="#888888"/>
                     </Trigger>
                     <Trigger Property="IsGrouping" Value="true">
                        <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
                     </Trigger>
                     <Trigger Property="Popup.AllowsTransparency" SourceName="Popup" Value="true">
                        <Setter TargetName="DropDownBorder" Property="CornerRadius" Value="4"/>
                        <Setter TargetName="DropDownBorder" Property="Margin" Value="0,2,0,0"/>
                     </Trigger>
                     <Trigger Property="IsEditable" Value="true">
                        <Setter Property="IsTabStop" Value="false"/>
                        <Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible"/>
                        <Setter TargetName="ContentSite" Property="Visibility" Value="Hidden"/>
                     </Trigger>
                     <Trigger Property="SelectedIndex" Value="1">
                        <Setter Property="FontWeight" Value="Bold"/>
                     </Trigger>
                     <Trigger Property="SelectedIndex" Value="2">
                        <Setter Property="FontWeight" Value="Bold"/>
                     </Trigger>
                     <Trigger Property="SelectedIndex" Value="3">
                        <Setter Property="FontWeight" Value="Bold"/>
                     </Trigger>
                  </ControlTemplate.Triggers>
               </ControlTemplate>
            </Setter.Value>
         </Setter>
      </Style>
      <Style x:Key="{x:Type ComboBoxItem}" TargetType="{x:Type ComboBoxItem}">
         <Setter Property="SnapsToDevicePixels" Value="true"/>
         <Setter Property="OverridesDefaultStyle" Value="true"/>
         <Setter Property="FontWeight" Value="Normal"/>
         <Setter Property="Template">
            <Setter.Value>
               <ControlTemplate TargetType="{x:Type ComboBoxItem}">
                  <Border Name="Border" Padding="2" SnapsToDevicePixels="true">
                     <ContentPresenter/>
                  </Border>
                  <ControlTemplate.Triggers>
                     <Trigger Property="IsHighlighted" Value="true">
                        <Setter TargetName="Border" Property="Background" Value="#DDDDDD"/>
                     </Trigger>
                     <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Foreground" Value="#888888"/>
                     </Trigger>
                  </ControlTemplate.Triggers>
               </ControlTemplate>
            </Setter.Value>
         </Setter>
      </Style>
   </Page.Resources>
   <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
      <TextBlock Margin="5" Text="What is your favorite primary colour?"/>
      <ComboBox Width="150" SelectedIndex="0">
         <ComboBoxItem>No Preference</ComboBoxItem>
         <ComboBoxItem>Red</ComboBoxItem>
         <ComboBoxItem>Green</ComboBoxItem>
         <ComboBoxItem>Blue</ComboBoxItem>
      </ComboBox>
   </StackPanel>
</Page>

I used the ContentTemplate property of the ContentPresenter in ComboBox to add a custom data template (SelectionBoxTextTemplate). That TextBlock grabs its FontWeight from an ancestor combo-box. I then added a template for the individual items, that forces them to normal font weight. This got the result you were looking for:

我使用ComboBox中ContentPresenter的ContentTemplate属性添加自定义数据模板(SelectionBoxTextTemplate)。 TextBlock从祖先组合框中获取FontWeight。然后我为各个项添加了一个模板,强制它们达到正常的字体粗细。这得到了您正在寻找的结果:

如何有条件地仅设置ComboBox所选项目中的文本样式?

#2


2  

You need to apply your trigger to the ComboBoxItem itself. Unless you've changed the behavior of the ComboBox, all items are displayed within containers (which are used to apply styles and templates) and the default container used by a ComboBox is a ComboBoxItem.

您需要将触发器应用于ComboBoxItem本身。除非您更改了ComboBox的行为,否则所有项都显示在容器中(用于应用样式和模板),ComboBox使用的默认容器是ComboBoxItem。

<Style TargetType="ComboBoxItem">
  <Style.Triggers>
    <Trigger Property="IsSelected" Value="True">
      <Setter Property="FontWeight" Value="Bold" />
    </Trigger>
  </Style.Triggers>
</Style>

You'll need to add your existing triggers to compensate for not bolding the selection when it is No Preference.

您需要添加现有触发器,以补偿在没有首选项时不选择粗体。

#3


-4  

I'm not an expert on WPF, but in Windows Forms the answer is called "OwnerDraw." This means that your code is responsible for drawing the control, instead of relying on the default behavior. When you're drawing it yourself, you can apply any style you want - including the ability to draw different items with different styles.

我不是WPF的专家,但在Windows Forms中,答案称为“OwnerDraw”。这意味着您的代码负责绘制控件,而不是依赖于默认行为。当您自己绘制时,可以应用任何您想要的样式 - 包括绘制具有不同样式的不同项目的能力。

I did a quick web search for "combobox ownerdraw" and got over 1,000,000 hits. You're not the only one that needs to do this, so you're sure to find a decent tutorial pretty quickly.

我对“combobox ownerdraw”进行了快速网络搜索,并获得了超过1,000,000次点击。你不是唯一需要这样做的人,所以你肯定会很快找到一个体面的教程。

#1


5  

There is no need to get into anything as despicable as owner-draw-- we are talking about WPF here, not WinForms. In WinForms, your only solution was to write more code. In WPF, we can solve this problem with a few very simple custom templates. For this example, I used Kaxaml, a free light-weight XAML editor. No code-behind was required. Kaxaml comes packed with a bunch of "starter" styles called Simple Styles. I used the ComboBox Simple Style and made modifications from that. So although this looks like a lot of XAML, I really just started with the boilerplate one and added a couple lines.

没有必要像业主那样进入任何卑鄙的东西 - 我们在这里讨论的是WPF,而不是WinForms。在WinForms中,您唯一的解决方案是编写更多代码。在WPF中,我们可以使用一些非常简单的自定义模板来解决这个问题。在这个例子中,我使用了Kaxaml,一个免费的轻量级XAML编辑器。不需要代码隐藏。 Kaxaml包含了一系列名为Simple Styles的“入门”样式。我使用了ComboBox Simple Style并对其进行了修改。因此,虽然这看起来像很多XAML,但我真的只是从样板文件开始,并添加了几行。

You can probably think of more elegant ways of triggering the font weight change; I used SelectedIndex.

您可以想到更优雅的方式来触发字体重量变化;我使用了SelectedIndex。

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
   <Page.Resources>
      <DataTemplate x:Key="SelectionBoxTextTemplate">
         <TextBlock FontWeight="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ComboBox}}, Path=FontWeight}" Text="{Binding}"/>
      </DataTemplate>
      <ControlTemplate x:Key="ComboBoxToggleButton" TargetType="{x:Type ToggleButton}">
         <Grid>
            <Grid.ColumnDefinitions>
               <ColumnDefinition/>
               <ColumnDefinition Width="20"/>
            </Grid.ColumnDefinitions>
            <Border
               x:Name="Border"
               Grid.ColumnSpan="2"
               Background="#C0C0C0"
               BorderBrush="#404040"
               BorderThickness="1"
               CornerRadius="2"/>
            <Border
               Grid.Column="0"
               Margin="1"
               Background="#FFFFFF"
               BorderBrush="#404040"
               BorderThickness="0,0,1,0"
               CornerRadius="2,0,0,2"/>
            <Path
               x:Name="Arrow"
               Grid.Column="1"
               HorizontalAlignment="Center"
               VerticalAlignment="Center"
               Data="M 0 0 L 4 4 L 8 0 Z"
               Fill="#404040"/>
         </Grid>
         <ControlTemplate.Triggers>
            <Trigger Property="ToggleButton.IsMouseOver" Value="true">
               <Setter TargetName="Border" Property="Background" Value="#808080"/>
            </Trigger>
            <Trigger Property="ToggleButton.IsChecked" Value="true">
               <Setter TargetName="Border" Property="Background" Value="#E0E0E0"/>
            </Trigger>
            <Trigger Property="IsEnabled" Value="False">
               <Setter TargetName="Border" Property="Background" Value="#EEEEEE"/>
               <Setter TargetName="Border" Property="BorderBrush" Value="#AAAAAA"/>
               <Setter Property="Foreground" Value="#888888"/>
               <Setter TargetName="Arrow" Property="Fill" Value="#888888"/>
            </Trigger>
         </ControlTemplate.Triggers>
      </ControlTemplate>
      <Style x:Key="{x:Type ComboBox}" TargetType="{x:Type ComboBox}">
         <Setter Property="SnapsToDevicePixels" Value="true"/>
         <Setter Property="OverridesDefaultStyle" Value="true"/>
         <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
         <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
         <Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
         <Setter Property="MinWidth" Value="120"/>
         <Setter Property="MinHeight" Value="20"/>
         <Setter Property="Template">
            <Setter.Value>
               <ControlTemplate TargetType="{x:Type ComboBox}">
                  <Grid>
                     <ToggleButton
                        Name="ToggleButton"
                        Grid.Column="2"
                        ClickMode="Press"
                        Focusable="false"
                        IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
                        Template="{StaticResource ComboBoxToggleButton}">
                     </ToggleButton>
                     <ContentPresenter
                        Name="ContentSite"
                        HorizontalAlignment="Left"
                        Margin="3,3,23,3"
                        VerticalAlignment="Center"
                        Content="{TemplateBinding SelectionBoxItem}"
                        ContentTemplate="{StaticResource SelectionBoxTextTemplate}"
                        ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
                        IsHitTestVisible="False"/>
                     <TextBox
                        x:Name="PART_EditableTextBox"
                        HorizontalAlignment="Left"
                        Margin="3,3,23,3"
                        VerticalAlignment="Center"
                        Background="Transparent"
                        Focusable="False"
                        IsReadOnly="{TemplateBinding IsReadOnly}"
                        Style="{x:Null}"
                        Visibility="Hidden"/>
                     <Popup
                        Name="Popup"
                        AllowsTransparency="True"
                        Focusable="False"
                        IsOpen="{TemplateBinding IsDropDownOpen}"
                        Placement="Bottom"
                        PopupAnimation="Slide">
                        <Grid
                           Name="DropDown"
                           MaxHeight="{TemplateBinding MaxDropDownHeight}"
                           MinWidth="{TemplateBinding ActualWidth}"
                           SnapsToDevicePixels="True">
                           <Border
                              x:Name="DropDownBorder"
                              Background="#FFFFFF"
                              BorderBrush="#888888"
                              BorderThickness="1"/>
                           <ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
                              <StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained"/>
                           </ScrollViewer>
                        </Grid>
                     </Popup>
                  </Grid>
                  <ControlTemplate.Triggers>
                     <Trigger Property="HasItems" Value="false">
                        <Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/>
                     </Trigger>
                     <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Foreground" Value="#888888"/>
                     </Trigger>
                     <Trigger Property="IsGrouping" Value="true">
                        <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
                     </Trigger>
                     <Trigger Property="Popup.AllowsTransparency" SourceName="Popup" Value="true">
                        <Setter TargetName="DropDownBorder" Property="CornerRadius" Value="4"/>
                        <Setter TargetName="DropDownBorder" Property="Margin" Value="0,2,0,0"/>
                     </Trigger>
                     <Trigger Property="IsEditable" Value="true">
                        <Setter Property="IsTabStop" Value="false"/>
                        <Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible"/>
                        <Setter TargetName="ContentSite" Property="Visibility" Value="Hidden"/>
                     </Trigger>
                     <Trigger Property="SelectedIndex" Value="1">
                        <Setter Property="FontWeight" Value="Bold"/>
                     </Trigger>
                     <Trigger Property="SelectedIndex" Value="2">
                        <Setter Property="FontWeight" Value="Bold"/>
                     </Trigger>
                     <Trigger Property="SelectedIndex" Value="3">
                        <Setter Property="FontWeight" Value="Bold"/>
                     </Trigger>
                  </ControlTemplate.Triggers>
               </ControlTemplate>
            </Setter.Value>
         </Setter>
      </Style>
      <Style x:Key="{x:Type ComboBoxItem}" TargetType="{x:Type ComboBoxItem}">
         <Setter Property="SnapsToDevicePixels" Value="true"/>
         <Setter Property="OverridesDefaultStyle" Value="true"/>
         <Setter Property="FontWeight" Value="Normal"/>
         <Setter Property="Template">
            <Setter.Value>
               <ControlTemplate TargetType="{x:Type ComboBoxItem}">
                  <Border Name="Border" Padding="2" SnapsToDevicePixels="true">
                     <ContentPresenter/>
                  </Border>
                  <ControlTemplate.Triggers>
                     <Trigger Property="IsHighlighted" Value="true">
                        <Setter TargetName="Border" Property="Background" Value="#DDDDDD"/>
                     </Trigger>
                     <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Foreground" Value="#888888"/>
                     </Trigger>
                  </ControlTemplate.Triggers>
               </ControlTemplate>
            </Setter.Value>
         </Setter>
      </Style>
   </Page.Resources>
   <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
      <TextBlock Margin="5" Text="What is your favorite primary colour?"/>
      <ComboBox Width="150" SelectedIndex="0">
         <ComboBoxItem>No Preference</ComboBoxItem>
         <ComboBoxItem>Red</ComboBoxItem>
         <ComboBoxItem>Green</ComboBoxItem>
         <ComboBoxItem>Blue</ComboBoxItem>
      </ComboBox>
   </StackPanel>
</Page>

I used the ContentTemplate property of the ContentPresenter in ComboBox to add a custom data template (SelectionBoxTextTemplate). That TextBlock grabs its FontWeight from an ancestor combo-box. I then added a template for the individual items, that forces them to normal font weight. This got the result you were looking for:

我使用ComboBox中ContentPresenter的ContentTemplate属性添加自定义数据模板(SelectionBoxTextTemplate)。 TextBlock从祖先组合框中获取FontWeight。然后我为各个项添加了一个模板,强制它们达到正常的字体粗细。这得到了您正在寻找的结果:

如何有条件地仅设置ComboBox所选项目中的文本样式?

#2


2  

You need to apply your trigger to the ComboBoxItem itself. Unless you've changed the behavior of the ComboBox, all items are displayed within containers (which are used to apply styles and templates) and the default container used by a ComboBox is a ComboBoxItem.

您需要将触发器应用于ComboBoxItem本身。除非您更改了ComboBox的行为,否则所有项都显示在容器中(用于应用样式和模板),ComboBox使用的默认容器是ComboBoxItem。

<Style TargetType="ComboBoxItem">
  <Style.Triggers>
    <Trigger Property="IsSelected" Value="True">
      <Setter Property="FontWeight" Value="Bold" />
    </Trigger>
  </Style.Triggers>
</Style>

You'll need to add your existing triggers to compensate for not bolding the selection when it is No Preference.

您需要添加现有触发器,以补偿在没有首选项时不选择粗体。

#3


-4  

I'm not an expert on WPF, but in Windows Forms the answer is called "OwnerDraw." This means that your code is responsible for drawing the control, instead of relying on the default behavior. When you're drawing it yourself, you can apply any style you want - including the ability to draw different items with different styles.

我不是WPF的专家,但在Windows Forms中,答案称为“OwnerDraw”。这意味着您的代码负责绘制控件,而不是依赖于默认行为。当您自己绘制时,可以应用任何您想要的样式 - 包括绘制具有不同样式的不同项目的能力。

I did a quick web search for "combobox ownerdraw" and got over 1,000,000 hits. You're not the only one that needs to do this, so you're sure to find a decent tutorial pretty quickly.

我对“combobox ownerdraw”进行了快速网络搜索,并获得了超过1,000,000次点击。你不是唯一需要这样做的人,所以你肯定会很快找到一个体面的教程。