Fluent xaml 主题编辑器的 uwp 组合框 header 问题

uwp combobox header issue with Fluent xaml theme editor

我制作了一个自定义组合框样式,其中边框环绕 header 以及组合框内容本身。它按预期工作正常并且 header 显示正常,但后来我打开了 "Fluent xaml theme editor"(来自商店的 uwp 主题生成器)并将其保留为默认值并将主题导出到我的 "app.xaml" 和现在 header 已经消失了。下面是重现问题的 link,只需打开项目并 运行 它,你会看到在浅色和深色主题上组合框上没有 header。

重现问题项目:https://github.com/touseefbsb/ComboBoxThemeIssue

最低目标:1803

目标sdk:1809/1903(1809仅在深色主题中显示header,1903在两个主题中均不显示header)

输出

代码

主页

<Pivot>
        <PivotItem Header="Dropdowns">
            <PivotItem.Resources>
                <DataTemplate x:Key="dropdowns">
                    <StackPanel Background="{ThemeResource SystemAltHighColor}">
                        <ComboBox Header="Header">
                            <ComboBoxItem>123</ComboBoxItem>
                            <ComboBoxItem>456</ComboBoxItem>
                            <ComboBoxItem>789</ComboBoxItem>
                        </ComboBox>
                    </StackPanel>
                </DataTemplate>
            </PivotItem.Resources>
            <Pivot>
                <PivotItem Header="Light" RequestedTheme="Light">
                    <ContentControl ContentTemplate="{StaticResource dropdowns}" />
                </PivotItem>
                <PivotItem Header="Dark" RequestedTheme="Dark">
                    <ContentControl ContentTemplate="{StaticResource dropdowns}" />
                </PivotItem>
            </Pivot>
        </PivotItem>
    </Pivot>

App.xaml

(https://github.com/touseefbsb/ComboBoxThemeIssue/blob/master/ComboBoxThemeIssue/ComboBoxThemeIssue/App.xaml)

更新 1

在进一步调查中,我发现从 colorpelleteResources 标签中删除 "AltMediumLow" 可以解决问题,但这很奇怪,因为它不应该被删除,因为它是 fluent 主题编辑器默认生成的主题的一部分。

在App.xaml中的HeaderedComboBoxStyle中,Fluent xaml主题编辑器生成的样式只为Grid定义了两行,让名为Background的Border占据两条线,所以 Border 覆盖 header。此外,它还将 header 的 Visibility 设置为 Collapsed 以隐藏它。但是在ComboBox的默认样式中,它设置了三行,第一行放header,第二行和第三行放Boder。所以你可以像默认样式一样改,例如:

App.xaml:

......
<ControlTemplate TargetType="ComboBox">
    <Grid x:Name="LayoutRoot">
        ......
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="32" />
         </Grid.ColumnDefinitions>

         <ContentPresenter  x:Name="HeaderContentPresenter"
                            Margin="{ThemeResource ComboBoxHeaderThemeMargin}"
                            x:DeferLoadStrategy="Lazy"
                            Content="{TemplateBinding Header}"
                            ContentTemplate="{TemplateBinding HeaderTemplate}"
                            FlowDirection="{TemplateBinding FlowDirection}"
                            FontWeight="{ThemeResource ComboBoxHeaderThemeFontWeight}"
                            Visibility="Visible" />
         <Border x:Name="Background"
                 Grid.RowSpan="2"
                 Grid.ColumnSpan="2"
                 Background="{TemplateBinding Background}"
                 BorderBrush="{TemplateBinding BorderBrush}"
                 BorderThickness="{TemplateBinding BorderThickness}"
                 Control.IsTemplateFocusTarget="True" />
         ......
     </Grid>
 </ControlTemplate>

更新:

基于App.xaml中的HeaderedComboBoxStyle,Border的Background名为"Background" templateBinding Background,Background 属性与ComboBoxBackground绑定。

选中ComboBoxBackground点击F12,会跳转到generic.xaml文件,然后可以看到绑定了SystemControlBackgroundAltMediumLowBrush的ComboBoxBackground,实际上SystemControlBackgroundAltMediumLowBrush的Color是等于 SystemAltMediumLowColor 的。在这种情况下,colorPelleteResources 中的 AltMediumLow 表示 SystemAltMediumLowColor。所以实际上,背景 属性 与 AltMediumLow.

绑定

当Light主题中AltMediumLow设置为白色时,Border的背景会变成白色并覆盖header,所以header无法显示。您可以在不删除 AltMediumLow 的情况下删除边框背景或将其设置为透明。

并且当您从colorpelleteResources标签中移除"AltMediumLow"时,AltMediumLow的颜色将默认设置为透明,因此边框的背景也是透明的,header将显示。

<Border
        x:Name="Background"
        Grid.RowSpan="2"
        Grid.ColumnSpan="2"
        Background="Transparent"
        BorderBrush="{TemplateBinding BorderBrush}"
        BorderThickness="{TemplateBinding BorderThickness}"
        Control.IsTemplateFocusTarget="True" />