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. python字符串方法学习笔记

    # 一.字符串大小写转换# 字符串首字符大写print("hello world".capitalize())# 将字符串变为标题print("hello WORLD&q ...

  2. eclipse导入了jar查看不了源码解决方法

    当导入源码的时候ctrl+左键的时候,还是查看不了源码.问题一直困扰我很久,百度了很多方法.现在分享下解决的方法. 经过简单整理,如下: 第一步:下载JAD . jad官方地址的官方下载地址是: ht ...

  3. android jni控制gpio (rk3288)

    1.添加驱动程序 2.编写jni c程序编译为库给java调用 3.app调用jni静态链接库操作底层驱动 1.添加驱动程序 修改/work/rk3288/firefly-rk3288_android ...

  4. 九、结构模式之装饰(Decorator)模式

    装饰模式又叫包装模式,装饰模式以客户端透明的方式扩展对象的功能,是继承关系的一个替代方案.装饰模式可以在不使用创造更多的子类的情况下,将对象的功能加以扩展. 装饰模式结构图如下: 其包含的角色就分为: ...

  5. ivew-admin 导入excel

    1.使用上传组件 <Upload ref="upload" name="importData" action="/api/device/impo ...

  6. 割边的tarjan算法

    与割点唯一一点不同是low[v]>=dfn[u]变为low[v]>dfn[u] 代码如下: bool vis[maxn]; int dfn[maxn],low[maxn]; int cnt ...

  7. MySQL数据库基本操作以及SQL语句

    连接mysql的语法 mysql -u用户名 -p密码 [-h主机名] [-P端口号] 在一个mysql服务器中, 可以有多个mysql数据库(本质是一个文件夹) 在一个mysql数据库中, 可以有多 ...

  8. IPv6时代已来:双十一中的IPv6大规模应用实践

    摘要: 刚刚过去的双十一,大家对猫晚.抢红包.组团购还记忆犹新.大家不了解的是,不知不觉间,你可能已经成为首批互联网IPv6用户了.今年天猫双十一期间,阿里巴巴全面支持了IPv6,这是IPv6在我国的 ...

  9. LG1010 幂次方

    题目描述 任何一个正整数都可以用2的幂次方表示.例如 137=2^7+2^3+2^0 同时约定方次用括号来表示,即a^b 可表示为a(b). 由此可知,137可表示为: 2(7)+2(3)+2(0) ...

  10. SQL必知必会——插入数据(十五)

    1.数据插入 INSERT用来将行插入(或添加)到数据库表.插入有几种方式: 插入完整的行插入行的一些部分插入某些查询的结果注意:1.使用INSERT语句可能需要客户端/服务端DBMS中的特定安全权限 ...