如何处理悬停状态等等?
可以为SystemControlHighlightBaseHighBrush
:
Button
之类的画笔
<SolidColorBrush x:Key="SystemControlHighlightBaseHighBrush" Color="White" />
如果任何其他控件使用该画笔,它也会使用此值,这是不需要的。我找到的另一个选项是覆盖默认样式:
<!-- Default style for Windows.UI.Xaml.Controls.Button -->
<Style TargetType="Button">
<Setter Property="Background" Value="{ThemeResource SystemControlBackgroundBaseLowBrush}" />
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundTransparentBrush}" />
<Setter Property="BorderThickness" Value="{ThemeResource ButtonBorderThemeThickness}" />
<Setter Property="Padding" Value="8,4,8,4" />
<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="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid x:Name="RootGrid" Background="{TemplateBinding Background}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<Storyboard>
<PointerUpThemeAnimation Storyboard.TargetName="RootGrid" />
</Storyboard>
</VisualState>
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseMediumLowBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseHighBrush}" />
</ObjectAnimationUsingKeyFrames>
<PointerUpThemeAnimation Storyboard.TargetName="RootGrid" />
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlBackgroundBaseMediumLowBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightTransparentBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseHighBrush}" />
</ObjectAnimationUsingKeyFrames>
<PointerDownThemeAnimation Storyboard.TargetName="RootGrid" />
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlBackgroundBaseLowBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledBaseMediumLowBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledTransparentBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="ContentPresenter"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Content="{TemplateBinding Content}"
ContentTransitions="{TemplateBinding ContentTransitions}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Padding="{TemplateBinding Padding}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
AutomationProperties.AccessibilityView="Raw"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
在这里,我将更改ObjectAnimationUsingKeyFrames
中的值。但是,如果即将推出的Windows版本中的默认样式发生了变化,该怎么办?
目前,除了覆盖默认样式外,我没有别的办法。或许可以覆盖一些事件并设置例如那边的边框颜色。但我认为并非所有活动都可用,您每次都必须编写自定义按钮。
对于我来说,覆盖一个完整的样式以仅更改一个值看起来有些不对。你是如何处理这种情况的?
答案 0 :(得分:1)
TL; DR:是的,更改完整模板(不是样式)是最常用的方案。
这里有不同的要点:
因此,我的第一个选择是为您的应用定义新的主题,并确实覆盖完成新品牌所需的SystemControlHighlightBaseHighBrush
和其他ThemeResource
资源。
如果出于某种正当理由,您不希望使用ThemeResource
的所有控件更改为新主题,则必须覆盖整个控件模板(因为模板是一个块,因此全有或全无)。无需覆盖所有其他属性设置器(例如前景,背景,填充......)。
如果您非常幸运,您尝试更改的属性是模板化属性,您只需使用一个属性设置器来修复您的布局。
这种方法的缺点确实是SDK的未来版本可以更改给定控件的模板。一个例子是Windows 8 / 8.1和10之间的GridView / GridViewItem样式。到目前为止,大多数样式都向后兼容,这意味着你的应用程序将继续工作,但可能不符合最新的布局指南或错过一些性能改进。因此,最佳实践&#39;在最新模板上重新应用自定义布局更改(如果时间允许)。
A&#39;脏&#39;解决方案是&#39; hacking&#39;进入Visual Tree以在运行时更改属性(基于事件,...)。但这不会阻止您对未来的SDK更新进行可能的更改,因此我甚至不认为这是一个有效的选项。
最后一种方法是使用自定义控件,定义您自己的模板(对于较新的SDK版本也是同样的问题)或使用默认模板并覆盖OnApplyTemplate
并调整您想要的属性通过从Visual Tree获取它来改变。但同样的说法是,未来的SDK版本可能会删除树中的控件/状态并破坏您的代码。
结论:您选择的任一选项,未来的SDK版本都可能会破坏您的实施。