UWP 轻量级样式定义(Lightweight Styling)
在 UWP 中,可以通过给空间直接设置属性或在 Style 中设置属性来定制空间的样式;不过这样的样式定义十分有限,比如按钮按下时的样式就没法儿设置。当然可以通过修改 Template 来设置控件的样式,然而 UWP 中控件的样式代码实在是太多太复杂了,还不容易从 Blend 中复制了大量代码出来改,下个版本样式又不一样,于是我们就丢了不少功能。
本文将介绍 UWP 轻量级样式定义(Lightweight styling),你既不用写太多代码,又能获得更多的样式控制。
本文内容
轻量级样式定义
看一段简单的代码,你一定能立刻明白本文想说的是什么。
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Light">
<SolidColorBrush x:Key="ButtonBackground" Color="Transparent"/>
<SolidColorBrush x:Key="ButtonForeground" Color="#dd5145"/>
<SolidColorBrush x:Key="ButtonBorderBrush" Color="#dd5145"/>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</Page.Resources>
本段代码摘抄自 XAML Lightweight styling - UWP app developer - Microsoft Docs
▲ 按钮的颜色定制
以上代码可以写在 Page 中,即可在 Page 范围内获得这些主题资源的重写。当然,如果需要更大范围,可以考虑去 App 类中重写。
官网上举例的这种类型的样式定义其实普通的 Style 也能很容易实现的,真正厉害的是 Style 里设置不了的那些鼠标滑过颜色和鼠标按下颜色。于是,我们额外添加一些代码:
<SolidColorBrush x:Key="ButtonBackground" Color="Transparent"/>
<SolidColorBrush x:Key="ButtonForeground" Color="#dd5145"/>
<SolidColorBrush x:Key="ButtonBorderBrush" Color="#dd5145"/>
<SolidColorBrush x:Key="ButtonBackgroundPointerOver" Color="#10dd5145"/>
<SolidColorBrush x:Key="ButtonForegroundPointerOver" Color="#ffcd44"/>
<SolidColorBrush x:Key="ButtonBorderBrushPointerOver" Color="#ffcd44"/>
<SolidColorBrush x:Key="ButtonBackgroundPressed" Color="#10ca5100"/>
<SolidColorBrush x:Key="ButtonForegroundPressed" Color="#ca5100"/>
<SolidColorBrush x:Key="ButtonBorderBrushPressed" Color="#ca5100"/>
现在我们只是设置一些颜色值即修改了按钮在多种状态下的外观。而且在按下的过程中,还保留了按钮按下时的倾斜效果。
▲ 按钮更多的颜色定制
相比于 Template -> Edit Copy 这种重量级的样式与模板定义,在保证足够的样式定义的情况下,代码量是不是少了非常多了呢?
如何找到控件支持的主题资源
前面我们知道了如何定制轻量级样式,但实际做 UI 的时候,我怎么知道有哪些样式主题资源的值可以使用呢?
一种方法是直接看微软官方文档,比如这里 XAML theme resources;你可以在这篇文章中找到很多通用的主题资源的 Key 用来重写。不过实际上由于 Windows Community Toolkit 以及各种第三方控件库的存在,所以没有什么文档是可以把这些 Key 写全的;所以更重要的方法是我们能自己找到有哪些 Key 可以使用。
找到 Key 的方法和定义一个全新的 Style / Template 一样,都可以通过 Visual Studio 的设计器视图(或者 Blend)实现。
第一步:前往 Visual Studio 设计器视图
▲ Visual Studio 设计器视图
第二步:在其中一个你想定制样式的控件上 右键 -> 编辑模板 -> 编辑副本
▲ 编辑模板
特别注意,如果你发现你的 “编辑副本” 是灰色的,说明你已经定制过样式了。将你已经定制的样式删除后,就可以再编辑副本了。
▲ 灰色的 “编辑副本”
第三步:寻找你感兴趣的主题资源的 Key,记下来准备定义
在编辑副本后,你可以在副本的代码中找到按钮的原生样式定义。比如一个按钮的样式是这样的:
<Style x:Key="ButtonStyle1" TargetType="Button">
<Setter Property="Background" Value="{ThemeResource ButtonBackground}"/>
<Setter Property="Foreground" Value="{ThemeResource ButtonForeground}"/>
<Setter Property="BorderBrush" Value="{ThemeResource ButtonBorderBrush}"/>
<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="{StaticResource UseSystemFocusVisuals}"/>
<Setter Property="FocusVisualMargin" Value="-3"/>
<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="RootGrid" 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>
<PointerUpThemeAnimation Storyboard.TargetName="RootGrid"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" 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>
<PointerDownThemeAnimation Storyboard.TargetName="RootGrid"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" 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>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="ContentPresenter" AutomationProperties.AccessibilityView="Raw" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentTransitions="{TemplateBinding ContentTransitions}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
从中我们可以找到这些可以定义的主题资源 Key:
- ButtonBackground
- ButtonForeground
- ButtonBorderBrush
- ButtonBorderThemeThickness
- ContentControlThemeFontFamily
- ControlContentThemeFontSize
- ButtonBackgroundPointerOver
- ButtonBorderBrushPointerOver
- ButtonForegroundPointerOver
- ButtonBackgroundPressed
- ButtonBorderBrushPressed
- ButtonForegroundPressed
- ButtonBackgroundDisabled
- ButtonBorderBrushDisabled
- ButtonForegroundDisabled
第四步:轻量级样式定义
请先删除这份副本样式,这样你就可以进行 “轻量级样式定义” 了。代码量相比于上面这份完整样式可以少非常多。
UWP 轻量级样式定义(Lightweight Styling)的更多相关文章
- CSS样式定义的优先级顺序总结
CSS样式定义的优先级顺序总结 层叠优先级是: 浏览器缺省 < 外部样式表 < 内部样式表 < 内联样式 其中样式表又有: 类选择器 < 类派生选择器 < ID选择器 & ...
- mathtype样式系统使用技巧-通过样式定义来更改方程中的字体
本教程中,我们主要介绍MathType Desktop的样式系统.演示如何通过更改样式定义来更改方程中的字体.通过样式可以快速轻松地实现我们所需的公式格式,并统一所有公式的样式. 我们以如下公式来作为 ...
- JavaScript获取非行间样式/定义样式
html节点的样式分为以下几种 (1)浏览器默认样式 (2)引用样式(引用外部css文件的样式.style标签内定义的样式) 引用外部css样式:<link rel="styleshe ...
- Silverlight样式定义
方法一.定义在控件内部 <Canvas Background="Red" Height="100" HorizontalAlignment="L ...
- console 中的格式化打印(占位符),和样式定义
格式化打印 Gecko 9.0 (Firefox 9.0 / Thunderbird 9.0 / SeaMonkey 2.6) 首次发布对string substitutions的支持.你可以在传递给 ...
- js获取非行间样式/定义样式
<!--DOCTYPE html--> <html> <head> <meta charset="utf-8" /> <sty ...
- table的样式定义
table的cellpadding和cellpadding我们经常会用如下的方式来清除默认样式: <table cellspacing="0" cellpadding=&qu ...
- UWP appButtonBar样式
UWP 的appButtonBar使用<AppBarButton Icon = "Next" Label = "Next" /> Icon是 Sym ...
- 28. 表单css样式定义格式
form>table>tbody>tr>td{padding:5px;font-size:14px;font-family:"Microsoft YaHei" ...
随机推荐
- flask后端 获取不到form表单post 的文件
原文地址http://docs.jinkan.org/docs/flask/patterns/fileuploads.html <form> 标签被标记有 enctype=multipar ...
- 《Python网络编程基础》第四章 域名系统
域名系统(DNS) 是一个分布式的数据库,它主要用来把主机名转换成IP地址.DNS以及相关系统之所以存在,主要有以下两个原因: 它们可以使人们比较容易地记住名字,如www.baidu.com. 它 ...
- Java String、StringBuffer、StringBuilder有什么区别
① String是Java语言非常基础和重要的类,提供了构造和管理字符串的各种基本逻辑.它是典型的immutable类,被声明成final class,所有属性也都是final的,由于它的不可变性,类 ...
- python openpyxl 封装Execl常用操作的方法
封装Excel操作方法:先装openpyxl:pip install openpyxl==2.4.5(可以指定版本) 封装脚本:#encoding=utf-8 from openpyxl import ...
- java压缩zip文件中文乱码问题
用java来打包文件生成压缩文件,有两个地方会出现乱码 1.内容的中文乱码问题,这个问题网上很多人给出了解决方法,两种:修改sun的源码:使用开源的类库org.apache.tools.zip.Zip ...
- MySQL备份与恢复-mysqldump备份与恢复
这片博文主要用来介绍MySQL的备份与恢复: MySQL的备份形式可以分为如下几种: 热备----即不停机备份 冷备----需要关闭MySQL,然后备份其数据文件.(停机备份一般是直接拷贝其datad ...
- redis未授权访问漏洞总结
Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API. 漏洞介绍: Redis 默认情况下,会绑定在 0.0.0.0 ...
- ZLYZD团队第四周项目总结
ZLYD团队第四周项目总结 项目进展 将Wall.java.Gold.java.Player.java.Fruit.java.Enemy.java.Ticker.java和Packman.java七个 ...
- 16s workfollw
http://bioconductor.org/packages/devel/bioc/vignettes/metagenomeFeatures/inst/doc/Example_16S_Annota ...
- Proxy(代理)
意图: 为其他对象提供一种代理以控制对这个对象的访问. 适用性: 在需要用比较通用和复杂的对象指针代替简单的指针的时候,使用Proxy模式.下面是一 些可以使用Proxy 模式常见情况: 1) 远程代 ...