以今天的眼光来看,一个好应用首先是要有好的用户体验。而好的用户体验最直观的就来自于用户界面。好的用户界面则须要好的设计,更须要好的实现。今天咱们就向你们分享一下咱们在使用Xaml实现界面设计上的一点心得。git
咱们拿到的设计,大可能是一张红线图,布满了距离,字号,色号,事无巨细的量化了咱们的用户界面。若是咱们就这样把各类属性照搬到上Xaml文件中,那看起来就很是不妙了,好比这样:github
<TextBlock Text="首页"FontFamily =" Segoe WP "FontSize ="24"FontWeight =" Normal "TextTrimming =" CharacterEllipsis "TextWrapping =" Wrap "MaxLines ="2" Foreground="#FF297ACD " ></TextBlock> express
一个看起来还好,可是一般咱们的页面上不可能只有这一个控件。要是有上10个20个,那若是要修改其中一个属性可真是得看花了眼啊。windows
很幸运,咱们在Universal应用的开发中能够把控件的相同属性概括为资源(Resource),再在须要的时候应用到控件上就能够了。app
有些很重要的单独的属性,以颜色为例,不一样控件都会使用,却只有几个值,Universal应用能够把它单独抽象成一种 StaticResource 资源--Brush 。将它应用到控件的 Foreground 或者Background 之类的属性上时,就会像"brush(刷子)"同样把控件变为它的颜色。其中经常使用的SolidColorBrush 能够写成这样:字体
<SolidColorBrush x:Key=" PostTitleFont" Color="#FF297ACD"/> this
将它放到资源字典或者页面的<Page.Resources> 中,就能够经过{StaticResource Brush的x:Key的值} 的形式来应用了。spa
而同一种控件的多个相同属性,咱们能够把它们概括成Style这种StaticResource资源,存在当前页面的 <Page.Resources> 中:设计
<Page.Resources> 3d
<SolidColorBrush x:Key=" PostTitleFont" Color="#FF297ACD"/>
<Style x:Key="PostTitleFont" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Segoe WP"/>
<Setter Property="FontSize" Value="24"/>
<Setter Property="FontWeight" Value="Normal"/>
<Setter Property="TextTrimming" Value="CharacterEllipsis"/>
<Setter Property="TextWrapping" Value="Wrap"/>
<Setter Property="MaxLines" Value="2"/>
<Setter Property="Foreground" Value="{StaticResourcePostTitleFont }"/>
</Style>
</Page.Resources>
Style 的 TargetType 属性指明了Style能够应用的元素,好比TargetType="TextBlock" 的Style是不能应用到Image 元素上的。而Style中包含的就是要应用的属性了,以 <Setter Property="属性名" Value="属性值"/> 这样的形式。
那么咱们在当前页面的须要应用Sytle的地方,好比上面的状况,就只须要经过Style的x:Key 属性来应用:
<TextBlock Text="首页" Style="{StaticResource PivotTitleFont}"></TextBlock>
咱们能够看到 Style="{StaticResource PivotTitleFont}" 中的 PivotTitleFont 就是 Style的 x:Key 属性,这样style就可以应用到 TextBlock 上了。
并且Style还能继承。好比我要一个 PostSubTitleFont, 只要字体比PostTitleFont 小一点。那我就能够这么写:
<Style x:Key="PostSubTitleFont" TargetType="TextBlock" BasedOn="{StaticResource PostTitleFont}">
<Setter Property="FontSize" Value="20"></Setter>
</Style>
这样一来若是我想改动它们的字体,只要在PostTitleFont中修改就能够了。是否是很方便?
固然咱们一般也不止有一个页面,若是不想在每一个页面中都把 Style 和 Brush 都贴一遍,就须要资源字典文件出场了。在咱们的项目中添加一个资源字典文件:
再把咱们的Style和 Brush都写在里面。而后在须要使用这些Style和 Brush的页面添加形以下面的代码把资源词典引用上就能够啦:
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Page.Resources>
固然,咱们既然是Universal应用,能不能把Styl和 Brushe在Windows应用和Windows Phone应用间共享呢?答案是能够的。咱们只要把资源文件放在.share项目下面,再在App.xaml中添加它的引用就能够:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
这样Dictionary.xaml中的Style和 Brush就在Windows应用和Windows Phone应用的全部页面都有效了。
等等,那Windows应用和Windows Phone应用间有所区别的Style和 Brush怎么办呢?
也有办法。只要在Windows项目和Windows Phone项目中各添加一个同名的资源词典文件好比DifferentDictionary.xaml,把不一样的Style和 Brush写入,再在App.xaml中引用就可以实现了。
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary.xaml" />
<ResourceDictionary Source="DifferentDictionary.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
这样,咱们经过Resource 和资源词典文件大大简化了用户界面设计的实现过程,是否是很方便呢?
说到阅读软件的用户体验,就不得不提到夜间模式了。下面就说说咱们在Windows Phone应用上实现夜间模式的过程吧。
你们可能都在Windows Phone 设置的 开始屏幕+主题 中设置过背景和主题色,当咱们修改了背景的 黑/白 后,几乎全部的系统应用的背景色和文字的颜色都马上改变了,连重启应用都不用。
咱们实现的夜间模式正是利用了这个功能。
在Windows Phone应用中,若是咱们设置了当前 Page的 RequestedTheme 属性为Light 或者Dark的话就至关于咱们在系统设置里修改了背景黑/白。好比一般状况下咱们新建一个应用,默认的状况下都是黑底白字:
而若是咱们把Page的 RequestedTheme 属性设为的话,能够看到在设计视图中应用变成了白底黑字:
那么咱们经过settings页面的一个 ToggleSwitch控件实时切换RequestedTheme这一属性,就能够实时控制应用的各类颜色如背景色,文字颜色为Light或Dark对应的颜色。咱们把Light设为日间模式,Dark设为夜间模式。简单一点的状况下能够把 ToggleSwitch 的Toggled事件响应方法设为以下:
private void ts_LightMode_Toggled(object sender, RoutedEventArgs e)
{
if (this.RequestedTheme == ElementTheme.Light)
{
this.RequestedTheme = ElementTheme.Dark;
}
else
{
this.RequestedTheme = ElementTheme.Light;
}
}
接下来如何设置日间模式/夜间模式对应的颜色呢?
在以前的样式管理一节中咱们提到了经过{StaticResource PivotTitleFont } 的形式来应用 SolidColorBrush 资源,可是咱们在资源 PostTitleFont 定义的时候只写了一个值,系统会自动帮咱们转换么?事实上并无那么简单。咱们须要经过 ThemeResource 类型的资源预先设置好2种模式对应的颜色。应用了这种 ThemeResource 资源之后,这个控件就可以响应 RequestedTheme 属性的变化,即时切换显示对应模式的颜色。
那么怎样加入这种资源呢?咱们能够打开咱们的资源字典 Dictionary.xaml ,在里面加入这样一段代码:
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Light">
</ResourceDictionary>
<ResourceDictionary x:Key="Dark">
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
这里 x:Key 分别为Dark/ Light 的 ResourceDictionary 中,就是咱们存放对应两种模式的资源的地方。好比咱们但愿页面背景在日间模式下是 蓝色,夜间模式下是深灰色,就能够这么写:
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Light">
<SolidColorBrush x:Key="myPageBackground" Color="Blue"></SolidColorBrush>
</ResourceDictionary>
<ResourceDictionary x:Key="Dark">
<SolidColorBrush x:Key="myPageBackground" Color="DarkGray"></SolidColorBrush>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
在咱们的page中就能够这样应用 ThemeResource 资源了:
<Page
x:Class="my_universal.CnblogsMainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:my_universal"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
RequestedTheme="Light"
Background="{ThemeResourcemyPageBackground }">
是否是一点都不难呢?
另外咱们还发现有两点值得注意:
一是咱们能够覆盖系统的 ThemeResource 。咱们能够选中任意一个 TextBlock 控件,打开属性栏,选择 Foreground 属性的画笔资源。
能够看到下方以ThemeBrush结尾的都是系统的 ThemeResource 资源,只要在咱们的 x:Key 分别为Dark/ Light 的 ResourceDictionary 里加入和它们同名的资源,就可以覆盖它们了。
二是对于Flyout 类型的控件,应用到它上面的 ThemeResource 资源是相反的。就是说当RequestedTheme 属性为 Light 时,Flyout 类型的控件会应用 Dark ResourceDictionary 中的资源。反之亦然。
今天就先向你们分享这些心得,欢迎你们继续关注和拍砖,让咱们共同进步。
咱们的已经发布的应用和代码能够在下面找到:
Windows Phone Store App link:
http://www.windowsphone.com/zh-cn/store/app/博客园-uap/500f08f0-5be8-4723-aff9-a397beee52fc
Windows Store App link:
http://apps.microsoft.com/windows/zh-cn/app/c76b99a0-9abd-4a4e-86f0-b29bfcc51059
GitHub open source link:
https://github.com/MS-UAP/cnblogs-UAP
MSDN Sample Code:
https://code.msdn.microsoft.com/CNBlogs-Client-Universal-477943ab