【问题标题】:uwp combobox header issue with Fluent xaml theme editorFluent xaml 主题编辑器的 uwp 组合框标题问题
【发布时间】:2024-01-14 02:41:01
【问题描述】:

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

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

最小目标:1803

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

输出

代码

主页

<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 主题编辑器默认生成的主题的一部分。

【问题讨论】:

    标签: c# xaml uwp styles themes


    【解决方案1】:

    在App.xaml的HeaderedComboBoxStyle中,Fluent xaml主题编辑器生成的样式只为Grid定义了两行,让名为Background的Border占据了两行,所以Border覆盖了header。此外,它还将标题的可见性设置为Collapsed以隐藏它。但是在 ComboBox 的默认样式中,它设置了三行,将表头放在第一行,将 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文件,可以看到ComboBoxBackground绑定了SystemControlBackgroundAltMediumLowBrush,实际上SystemControlBackgroundAltMediumLowBrush的Color等于SystemAltMediumLowColor的颜色。在这种情况下,colorPelleteResources 中的 AltMediumLow 代表 SystemAltMediumLowColor。所以实际上,Background 属性与 AltMediumLow 绑定。

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

    并且当你从 colorpelleteResources 标签中删除“AltMediumLow”时,AltMediumLow 的颜色会默认设置为透明,因此边框的背景也是透明的,标题会显示。

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

    【讨论】:

    • 我想你误解了我的问题,我故意对默认样式进行了一些更改,以便背景边框也环绕标题,我的目标是将组合框上方的标题合并到组合框本身中一直按预期工作,直到我通过商店中的 fluent xaml 主题编辑器应用程序介绍了浅色和深色主题的调色板。希望澄清一下,如果我将标题保留在第一行和边框以及接下来的 2 行中,它会破坏我试图实现的风格。
    • 只要我在 app.xaml 中注释掉“Windows10version1809:ColorPaletteResources”标签,标题就会再次出现,所以我认为有些颜色会弄乱标题颜色。
    • 请查看问题中的Update1