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" ...
随机推荐
- Python: 字符串中嵌入变量
问题:想创建一个内嵌变量的字符串,变量被它的值替换掉 解决方案: ①Python并没有对在字符串中简单替换变量值提供直接的支持,但是通过字符串的format()方法来解决这个问题 ②如果要被替换的变量 ...
- qml学习笔记(二):可视化元素基类Item详解(上半场anchors等等)
原博主博客地址:http://blog.csdn.net/qq21497936本文章博客地址:http://blog.csdn.net/qq21497936/article/details/78516 ...
- 五,动态库(dll)的封装与使用
在项目开发中,我们经常会使用到动态库(dll),要么是使用别人的动态库,要么是将功能函数封装为动态库给别人用.那么如何封装和使用动态库呢?以下内容为你讲解. 1.动态库的封装 以vs2010为例,我们 ...
- Ubuntu 16.04 (官方命令行)安装MongoDB 3.6.2(社区版)
概述 使用本教程从 .deb 包在LTS Ubuntu Linux系统上安装MongoDB Community Edition. 虽然Ubuntu包含自己的MongoDB包,但官方的MongoDB社区 ...
- 20145104张家明 《Java程序设计》第3周学习总结
20145104张家明 <Java程序设计>第4周学习总结 教材学习内容总结 第四章 认识对象 4.1 类与对象 4.1.1 定义类 类定义时使用class关键词,建立实例要用new关键词 ...
- InstallShield的工程类型的选择
转载:http://blog.csdn.net/wuxiaoqrs/article/details/45717695 InstallScript vs. Basic MSI InstallScript ...
- Git提交撤销
场景:本地修改代码后,执行commit提交,但此时想撤销该提交. 执行命令: git reflog 查看所有commit历史 git reset --hard commitid 将当前远程 ...
- CF_321_B_NetFlow
CF_321_B 题面:据说题目描述是游戏王的规则,然而我并没有玩过.大概意思就是我方有m张攻击牌,敌方有n张牌(防御,攻击都有),如果一回合我方选择攻击牌(X)攻击敌方防守牌(Y)且$Vval_X ...
- UVa 10328 Coin Toss(Java大数+递推)
https://vjudge.net/problem/UVA-10328 题意: 有H和T两个字符,现在要排成n位的字符串,求至少有k个字符连续的方案数. 思路:这道题目和ZOJ3747是差不多的,具 ...
- HDU 3488 Tour(最小费用流:有向环最小权值覆盖)
http://acm.hdu.edu.cn/showproblem.php?pid=3488 题意: 给出n个点和m条边,每条边有距离,把这n个点分成1个或多个环,且每个点只能在一个环中,保证有解. ...