title author date CreateTime categories
win10 uwp 资源字典
lindexi
2018-2-13 17:23:3 +0800
2018-2-13 17:23:3 +0800
Win10 UWP

本文告诉大家如何定义、使用资源

本文主要翻译ResourceDictionary and XAML resource references - UWP app developer,里面的代码我重新写了一下,有一些不相同。

一般资源在 xaml 定义,定义的地方可以是在 Page ,请看下面的代码

<Page
x:Class="KrahfcjjqKzz.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Page.Resources>
<x:String x:Key="TalsdtiiKjsvk">林德熙</x:String>
<x:String x:Key="KsjdqKoqij">csdn</x:String>
</Page.Resources> <TextBlock Text="{StaticResource TalsdtiiKjsvk}" Foreground="Gray" VerticalAlignment="Center"/>
</Page>

可以看到,上面的代码在 Page 的资源定义了两个字符串,然后在控件使用了定义的资源。实际可以在 Resources 定义几乎任意的资源,但是要求这些资源有默认构造函数,而且支持定义为资源。例如支持共享的类型,styles、templates、brushes,在下面会告诉大家具体哪些元素是可以共享。

使用资源的方法是在需要使用的地方使用 StaticResource 获得。如果需要从后台拿到资源,请看后台获取资源

而 StaticResource 获得资源是通过一个特殊的寻找方法,这个方法在后面告诉大家。

资源的key

从上面的代码可以看到,所有的资源定义都有一个 Key ,通过这个 Key 就可以让 StaticResource 找到需要的资源。但是存在一些特殊的资源是可以不使用 Key 的,下面让我来告诉大家有哪些东西可以不添加 key

Style

对于 Style 和 ControlTemplate 等,具有TargetType表示这是属于哪个类型的 样式,如果不定义 Key ,那么在这个资源定义包起来的控件都会使用这个样式,请看下面的代码

<Page
x:Class="KrahfcjjqKzz.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Page.Resources>
<x:String x:Key="TalsdtiiKjsvk">林德熙</x:String>
<x:String x:Key="KsjdqKoqij">csdn</x:String>
<Style TargetType = "TextBlock">
<Setter Property="Margin" Value="10,10,10,10"/>
</Style>
</Page.Resources> <TextBlock Text="{StaticResource TalsdtiiKjsvk}" Foreground="Gray" VerticalAlignment="Center"/>
</Page>

可以看到,没有设置 TextBlock 的 Style ,但是自动就修改了 TextBlock 的样式

DataTemplate

对于 DataTemplate 也可以不给 Key ,因为一般的 DataTemplate 都会指定数据类型,所以对于没有指定 Key 的 DataTemplate 会自动用在他使用的数据类型

不过不建议使用这个方法

Name

对于已经定义了命名的资源可以不使用Key ,因为通过命名可以可以拿到资源。在资源定义 Name 是 UWP 才有的,在 WPF 是不能这样做,定义了 Name 可以很快在后台代码拿到资源,但是运行效率 Name 会比 Key 低,因为在页面 Loaded 之后需要初始化这个资源。

所有的元素都可以定义资源

实际上不只是页面可以添加资源,对所有的 FrameworkElement 都可以定义资源。如果大家还不知道什么是 FrameworkElement ,那么简单可以说,所有显示在界面的元素都是 FrameworkElement ,所以所有显示的元素都可以定义资源。包括面板和自定义控件。

而且资源的寻找居然靠近优先,也就是在页面定义的资源和在元素定义的资源,会先在元素找,如果元素可以找到资源,就不会在页面找

<Page
x:Class="TobHrv.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Page.Resources>
<x:String x:Key="Lindexi">林德熙</x:String>
</Page.Resources> <Border>
<Border.Resources>
<x:String x:Key="Lindexi">逗比开发者</x:String>
</Border.Resources>
<TextBlock Text="{StaticResource Lindexi}" Foreground="Gray" VerticalAlignment="Center"/>
</Border>
</Page>

可以看到这个软件运行显示的是 逗比开发者而不是 林德熙,因为相同的 Key 定义在元素,资源先在元素找,找到了就不会去页面找。资源寻找的方向是 TextBlock -> Border -> Page ,因为在 Boarder 就找到资源,所以在页面的资源就不会找了。通过这个方法可以自定义需要的资源,也就是在 App.xaml 定义一般使用的资源,然后在 Page 定义页面的资源,在元素定义特殊资源。

但是需要知道,如果使用的是 x:Bind ,那么只会在页面找,不会在元素找。这是很重要的,具体请看x:Bind 无法获得资源

合并资源字典

从上面的代码实际还是看不出资源存在的问题,实际上的资源需要的代码是比较多的,特别是特殊的 Style ,一个 Style 一般有很多行,如果都写在页面,那么需要看到的代码很多。所以建议的方法是把资源写在一个文件,这个文件就是资源文件。把资源写在文件可以让资源在多个项目使用,也可以在需要使用资源的项目使用,在不需要使用资源的项目就不添加。因为资源的创建也需要内存。

下面创建一个资源字典 SedpwbvkKbrjlpi.xaml ,在里面定义一个资源

<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:SqdSgjd"> <SolidColorBrush x:Key="brush" Color="Red"/> </ResourceDictionary>

在需要使用资源的地方可以用下面的代码引用这个资源

<Page
x:Class="SqdSgjd.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="SedpwbvkKbrjlpi.xaml"/>
</ResourceDictionary.MergedDictionaries> </ResourceDictionary>
</Page.Resources> <TextBlock Foreground="{StaticResource brush}" Text="林德熙" VerticalAlignment="Center"/>
</Page>

需要知道上面的代码存在两个问题,一个是资源的路径,需要把资源写为相对文件的路径,如果需要写绝对,那么请使用 ms-appx的方法。另外,对于资源的命名,都是用 Aa 的命名方式,而不是开头小写。

如果创建了另一个资源字典 KlgnkTbyt.xaml ,使用下面的代码可以引用这个字典

<Page
x:Class="SqdSgjd.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="SedpwbvkKbrjlpi.xaml"/>
<ResourceDictionary Source="KlgnkTbyt.xaml"/>
</ResourceDictionary.MergedDictionaries> </ResourceDictionary>
</Page.Resources> <TextBlock Foreground="{StaticResource brush}" Text="林德熙" VerticalAlignment="Center"/>
</Page>

但是如果在 KlgnkTbyt.xaml 也定义了一个在第一个字典也存在的 Key ? 会找到什么?实际上资源可以被重新定义,在后面的定义会覆盖前面的,所以如果有两个从重复定义,会使用后面一个。

主题资源

上面用的是静态的资源,如果需要跟着主题修改的资源就是主题资源。实际上主题字典和资源字典是相同的,不同在于定义。下面来创建一个不同颜色的主题

<!-- ShunTaosqtqal.xaml -->
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TkfoajhxcHbzw"> <SolidColorBrush x:Key="brush" Color="Red"/> </ResourceDictionary> <!-- DfwDcfgjr.xaml -->
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TkfoajhxcHbzw"> <SolidColorBrush x:Key="brush" Color="blue"/> </ResourceDictionary>

然后在引用的资源的时候使用 ThemeDictionaries ,请看下面

<Page
x:Class="TkfoajhxcHbzw.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary Source="ShunTaosqtqal.xaml.xaml" x:Key="Light"/>
<ResourceDictionary Source="DfwDcfgjr.xaml" x:Key="Dark"/>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</Page.Resources>
<TextBlock Foreground="{StaticResource brush}" Text="林德熙" VerticalAlignment="Center"/>
</Page>

现在使用暗主题的时候,显示的文字就会是蓝色,不过暗主题使用蓝色是比较不好的。

关于主题切换,请看[切换主题 (https://lindexi.gitee.io/post/win10-uwp-%E5%88%87%E6%8D%A2%E4%B8%BB%E9%A2%98.html )

共享的资源

所有定义资源的类都需要可以共享,因为会有很多个地方引用相同的资源,如果对于一个不可以共享的元素,如TextBlock 就不能定义为资源。

如果一个元素不能在逻辑树存在多个地方,那么这个元素就是不可共享的,所以几乎所有自己从 Object 定义的类都是可共享的,而所有从 FrameworkElement 继承的类都是不可共享的。

一般建议共享的资源:

  • Styles 和 templates , Style 和其他继承 FrameworkTemplate 可以共享

  • Brushes 和继承他的类

  • 包括 Storyboard 的动画

  • 点集

  • 数组

  • UI 相关的结构,如 Thickness 和 CornerRadius

  • xaml 固有类型,x:Boolean、x:String、x:Double 这些

  • 转换器

如果是自己定义的类,需要类有默认的构造函数。

用户控件

用户控件具有特殊的寻找资源范围,他的寻找范围一般都是用户控件本身的资源,对于用户控件之外的资源一般都是无法寻找。因为他有自己实现。但是在用户控件外面调用用户控件,给他的属性设置资源,就可以使用 App.xaml 定义的资源。

资源定义

最后需要告诉大家,资源的定义一般都是把共有的资源定义为字典。把全局需要使用的资源定义在 app.xaml ,因为如果在每个相同的页面都定义一次,那么在进入页面就需要重复资源,这样会浪费内存。创建资源也需要时间。但是如果在 App.xaml 定义太多资源,会降低软件的启动速度。所以建议是在 App.xaml 定义合适的资源。

2018-2-13-win10-uwp-资源字典的更多相关文章

  1. win10 uwp 使用 Microsoft.Graph 发送邮件

    在 2018 年 10 月 13 号参加了 张队长 的 Office 365 训练营 学习如何开发 Office 365 插件和 OAuth 2.0 开发,于是我就使用 UWP 尝试使用 Micros ...

  2. wpf 在引用外部的资源字典

    启动的APP.xaml

  3. win10 uwp 列表模板选择器

    本文主要讲ListView等列表可以根据内容不同,使用不同模板的列表模板选择器,DataTemplateSelector. 如果在 UWP 需要定义某些列的显示和其他列不同,或者某些行的显示和其他行不 ...

  4. win10 uwp DataContext

    本文告诉大家DataContext的多种绑法. 适合于WPF的绑定和UWP的绑定. 我告诉大家很多个方法,所有的方法都有自己的优点和缺点,可以依靠自己喜欢的用法使用.当然,可以在新手面前秀下,一个页面 ...

  5. win10 uwp 按下等待按钮

    我们经常需要一个按钮,在按下时,后台执行Task,这时不能再次按下按钮. 我们使用自定义控件,首先新建一个类,我把它命名是ProgressButton 一个进度条按钮,也就是我们按下时发生进度条,完成 ...

  6. win10 uwp 商业游戏

    本文告诉大家去做一个商业游戏,游戏很简单,几乎没有什么技术 游戏的开始,需要添加框架库,于是引用我自己写的库. 首先是创建一个启动页面,这个页面是显示启动的. 在显示启动的时候,是需要加载游戏需要使用 ...

  7. win10 uwp 线程池

    原文:win10 uwp 线程池 如果大家有开发 WPF 或以前的程序,大概知道线程池不是 UWP 创造的,实际上在很多技术都用到线程池. 为什么需要线程池,他是什么?如何在 UWP 使用线程池,本文 ...

  8. Win10 UWP版《芒果TV》v2.4.0直播超女,芒果台综艺一网打尽

    Win10 UWP版<芒果TV>直播超女,芒果台综艺一网打尽 Win10版UWP<芒果TV>自2015年9月登录商店以来,一直在持续更新,积极改进,拥有芒果台视频的独家点播和直 ...

  9. win10 uwp 如何使用DataTemplate

    这是数据模板,一般用在数组的绑定,显示数组中的元素. 假如我们有一个列表,列表里是书,包括书名.作者.还有出版,那么我们只有源信息,如何把它显示到我们的ListView,就需要DataTemplate ...

  10. win10 uwp 通过 Win2d 完全控制笔迹绘制逻辑

    本文来告诉大家如何通过 Win2d 完全控制笔迹绘制逻辑,本文适合用来实现复杂的自定义逻辑,可以完全控制笔迹的行为.包括在书写过程中切换模式,如进行手势擦除切换为橡皮擦模式 本文提供的方法适合用来做复 ...

随机推荐

  1. 【目录】sql server 进阶篇系列

    随笔分类 - sql server 进阶篇系列 sql server 下载安装标记 摘要: SQL Server 2017 的各版本和支持的功能 https://docs.microsoft.com/ ...

  2. C#程序的编译过程

    C#程序的编译过程,如下图 总结:编译器将C#代码编译成DLL/EXE,DLL/EXE包含metadata(清单数据,对代码的描述)和IL(中间语言),IL(中间语言)经过CLR/JIT第二次编译才是 ...

  3. YARN学习笔记

    分布式资源调度框架 Yet Another Resource Negotiator YARN 不同框架使用相同的系统资源 YARN的核心组件(架构) ResourceManager RM 整个集群同一 ...

  4. 【leetcode】929. Unique Email Addresses

    题目如下: Every email consists of a local name and a domain name, separated by the @ sign. For example, ...

  5. js插件-简单拖拽

    前端开发的时候,有好多地方用到拖拽效果,当然 http://jqueryui.com/draggable/  是个不错的选择,but 我是个打破砂锅问到底的人,抽点时间用js小小的实现了类似的插件,话 ...

  6. Mybatis基于XML配置SQL映射器(一)

    Durid和Mybatis开发环境搭建 SpringBoot搭建基于Spring+SpringMvc+Mybatis的REST服务(http://www.cnblogs.com/nbfujx/p/76 ...

  7. apue 第10章 信号signal

    每种信号都有名字,都是以SIG开头 信号机制最简单的接口是signal函数 #include <signal.h> typedef void (*sighandler_t)(int); s ...

  8. ribbon学习

    spring cloud 中的负载均衡有ribbon和feign 引入ribbon依赖 <!--ribbon相关--> <dependency> <groupId> ...

  9. windows系统下tomcat启动startup.bat一闪而过

    遇到运行startup.bat后,一个窗口一闪而过的问题 tomcat在启动时,会读取环境变量的信息,需要一个CATALINA_HOME 与JAVA_HOME的信息,CATALINA_HOME即tom ...

  10. C#调PowerShell在SCVMM中创建虚拟机时,实时显示创建进度

    关于c#调用PowerShell来控制SCVMM,网上有很多例子,也比较简单,但创建虚拟机的过程,是一个很漫长的时间,所以一般来说,创建的时候都希望可以实时的显示当前虚拟机的创建进度.当时这个问题困扰 ...