WinUI默认样式中的条件XAML Setter在UWP中为何失效?
我从WinUI仓库复制了默认的Button样式到空UWP项目中,运行时出现错误:XAML二进制格式(XBF)生成器报告语法错误‘0x03e9’。移除<Style>内的条件Setter后项目可正常运行,但控件模板内的条件XAML能正常工作,请问哪里操作有误?
<Application x:Class="App1.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:contract7Present="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract,7)" xmlns:contract7NotPresent="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractNotPresent(Windows.Foundation.UniversalApiContract,7)" xmlns:local="using:Microsoft.UI.Xaml.Controls"> <Application.Resources> <Style x:Key="DefaultButtonStyle" TargetType="Button"> <Setter Property="Background" Value="{ThemeResource ButtonBackground}" /> <contract7Present:Setter Property="BackgroundSizing" Value="InnerBorderEdge" /> <Setter Property="Foreground" Value="{ThemeResource ButtonForeground}" /> <Setter Property="BorderBrush" Value="{ThemeResource ButtonBorderBrush}" /> <Setter Property="BorderThickness" Value="{ThemeResource ButtonBorderThemeThickness}" /> <contract7NotPresent:Setter Property="Padding" Value="11,5,11,5" /> <contract7Present:Setter Property="Padding" Value="{StaticResource ButtonPadding}" /> <Setter Property="HorizontalAlignment" Value="Left" /> <Setter Property="VerticalAlignment" Value="Center" /> <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" /> <Setter Property="FontWeight" Value="Normal" /> <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" /> <Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}" /> <Setter Property="FocusVisualMargin" Value="-3" /> <contract7Present:Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <ContentPresenter x:Name="ContentPresenter" Background="{TemplateBinding Background}" contract7Present:BackgroundSizing="{TemplateBinding BackgroundSizing}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" ContentTransitions="{TemplateBinding ContentTransitions}" contract7Present:CornerRadius="{TemplateBinding CornerRadius}" contract7NotPresent:CornerRadius="{ThemeResource ControlCornerRadius}" Padding="{TemplateBinding Padding}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" AutomationProperties.AccessibilityView="Raw" local:AnimatedIcon.State="Normal"> <contract7Present:ContentPresenter.BackgroundTransition> <contract7Present:BrushTransition Duration="0:0:0.083" /> </contract7Present:ContentPresenter.BackgroundTransition> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CommonStates"> <VisualState x:Name="Normal"/> <VisualState x:Name="PointerOver"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Background"> <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBackgroundPointerOver}" /> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="BorderBrush"> <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBorderBrushPointerOver}" /> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground"> <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundPointerOver}" /> </ObjectAnimationUsingKeyFrames> </Storyboard> <VisualState.Setters> <Setter Target="ContentPresenter.(local:AnimatedIcon.State)" Value="PointerOver"/> </VisualState.Setters> </VisualState> <VisualState x:Name="Pressed"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Background"> <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBackgroundPressed}" /> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="BorderBrush"> <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBorderBrushPressed}" /> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground"> <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundPressed}" /> </ObjectAnimationUsingKeyFrames> </Storyboard> <VisualState.Setters> <Setter Target="ContentPresenter.(local:AnimatedIcon.State)" Value="Pressed"/> </VisualState.Setters> </VisualState> <VisualState x:Name="Disabled"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Background"> <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBackgroundDisabled}" /> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="BorderBrush"> <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBorderBrushDisabled}" /> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground"> <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundDisabled}" /> </ObjectAnimationUsingKeyFrames> </Storyboard> <VisualState.Setters> <!-- DisabledVisual Should be handled by the control, not the animated icon. --> <Setter Target="ContentPresenter.(local:AnimatedIcon.State)" Value="Normal"/> </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> </ContentPresenter> </ControlTemplate> </Setter.Value> </Setter> </Style> </Application.Resources> </Application>
原因与解决方法
- UWP原生不支持样式级别的条件Setter:你用的
contract7Present:Setter这类条件Setter是WinUI(Microsoft.UI.Xaml)专属语法,UWP的XBF生成器无法识别<Style>根节点下的这种条件Setter,仅支持在控件模板内部使用属性级的条件XAML(比如模板里的contract7Present:BackgroundSizing)。 - 可行的解决方式:
- 若项目允许,直接升级为WinUI 3项目,原生支持这类WinUI特有的样式语法。
- 针对纯UWP项目,调整样式写法:
- 手动移除样式内的条件Setter,根据你的目标SDK版本,直接设置兼容的属性值;
- 或者在代码后台,通过
ApiInformation.IsApiContractPresent判断API契约版本,运行时给Button设置对应属性,规避XAML里的条件Setter语法。
- 基于UWP原生Button样式修改,不要直接复制WinUI的样式,两者的XAML语法支持范围有差异。
内容的提问来源于stack exchange,提问作者Mapplesoft
相关产品推荐
相关产品推荐

