WPF介绍了一个非常方便的概念:把数据储存为一种资源,无论是本地控件、本地窗口还是全局应用。数据可以是任何你想要的东西,从实际的信息到WPF控件的层次结构都行。这非常有用,你可以把数据放在一个地方,然后在其他地方调用它。

这个概念被广泛用在样式和模版,我们后面会详细讲到。也可以用在很多别的地方,就像本章要说明的地方,例子如下:

<span style="font-size:14px;"><Window x:Class="WpfTutorialSamples.WPF_Application.ResourceSample"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:sys="clr-namespace:System;assembly=mscorlib"Title="ResourceSample" Height="150" Width="350"><Window.Resources><sys:String x:Key="strHelloWorld">Hello, world!</sys:String></Window.Resources><StackPanel Margin="10"><TextBlock Text="{StaticResource strHelloWorld}" FontSize="56" /><TextBlock>Just another "<TextBlock Text="{StaticResource strHelloWorld}" />" example, but with resources!</TextBlock></StackPanel>
</Window></span>


资源使用x:Key属性来定义一个关键字,使用该关键字,就可以从应用的其他地方来引用了。你需要用到StaticResource这个标记扩展符。在上面的例子中,我定义了一个简单的字符串(Hello,world!),然后在两个不同的文本块里面进行引用。

StaticResource与DynamicResource

上面的例子我用了StaticResource这个标记扩展符来引用资源,其实还有另外一种形式:DynamicResource(动态资源)。
两者主要的区别是,静态资源只在XAML加载的时候引用一次。如果这个资源后面被修改了,并不会在前面引用的地方生效。动态资源正好相反,在需要时才引用,因此所做的更改都会影响到引用的地方。打个比方,一个是绑定到一个静态值,一个是绑定一个函数,这个函数监视值,每当值发生变化的时候发送给你。尽管严格意义上来讲不是这样的,但你可以这么理解,也就明白了什么时候用,用哪一种。动态资源也可以只在运行时使用,譬如在应用启动的时候从后台代码添加进来。
其他资源类型
共享一个简单的字符串其实是很容易的,然而,你可以做的更多。下面的例子,我将存储一个字符串数组,以及一个用于背景的渐变画笔。这应该让你明白你能用资源做很多事情。
<span style="font-size:14px;"><Window x:Class="WpfTutorialSamples.WPF_Application.ExtendedResourceSample"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:sys="clr-namespace:System;assembly=mscorlib"Title="ExtendedResourceSample" Height="160" Width="300"Background="{DynamicResource WindowBackgroundBrush}"><Window.Resources><sys:String x:Key="ComboBoxTitle">Items:</sys:String><x:Array x:Key="ComboBoxItems" Type="sys:String"><sys:String>Item #1</sys:String><sys:String>Item #2</sys:String><sys:String>Item #3</sys:String></x:Array><LinearGradientBrush x:Key="WindowBackgroundBrush"><GradientStop Offset="0" Color="Silver"/><GradientStop Offset="1" Color="Gray"/></LinearGradientBrush></Window.Resources><StackPanel Margin="10"><Label Content="{StaticResource ComboBoxTitle}" /><ComboBox ItemsSource="{StaticResource ComboBoxItems}" /></StackPanel>
</Window></span>

这次我们添加了一组额外的资源,窗体包含了一个简单的字符串,一个字符串数组和一个渐变画刷。字符串用于标签,数组用于下拉组合框,画刷用于整个窗口的背景。就像这样很多东西都可被存为资源。

本地资源和应用范围的资源

目前为止我们都是在窗口层存储资源,也就意味着你可以在整个窗口访问这些资源。
如果你只是想把资源用于具体的某个控件,你可以直接添加到控件里面,而不用在窗口层添加,这样更显本地化。工作情况一模一样,唯一的区别是你只能在这个控件范围内访问资源。
<span style="font-size:14px;"><StackPanel Margin="10"><StackPanel.Resources><sys:String x:Key="ComboBoxTitle">Items:</sys:String></StackPanel.Resources><Label Content="{StaticResource ComboBoxTitle}" />
</StackPanel></span>

上面的例子中,我们把资源添加到StackPanel控件里面,并用到子控件Label。只要是在StackPanel里的子控件都可以使用这个资源,而在StackPanel外面的控件则无法使用这个资源。

如果你想在几个窗口之间访问资源,也是可以做到的。App.xaml包含了像窗口或者其他WPF控件那样的资源,如果你把这些资源放到App.xaml中,那么这些资源就能被全局访问了。工作情况和窗口中的一样。
<span style="font-size:14px;"><Application x:Class="WpfTutorialSamples.App"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:sys="clr-namespace:System;assembly=mscorlib"StartupUri="WPF application/ExtendedResourceSample.xaml"><Application.Resources><sys:String x:Key="ComboBoxTitle">Items:</sys:String></Application.Resources>
</Application></span>

WPF自动逐级向上搜索,从本地控件到整个窗口,再到App.xaml,来找到这个资源。

<span style="font-size:14px;"><Label Content="{StaticResource ComboBoxTitle}" /></span>

后台代码的资源
我们通过一个标记扩展,访问了XAML的所有资源。同样的,你也可以从后台代码访问各种资源,在某些场景下非常有用。前面的例子我们把资源放在不同的地方,因此接下来的例子,我们将资源放在在三个不同的范畴,然后在后台代码访问它们。

App.xaml:
<span style="font-size:14px;"><Application x:Class="WpfTutorialSamples.App"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:sys="clr-namespace:System;assembly=mscorlib"StartupUri="WPF application/ResourcesFromCodeBehindSample.xaml"><Application.Resources><sys:String x:Key="strApp">Hello, Application world!</sys:String></Application.Resources>
</Application></span>

Window:

<span style="font-size:14px;"><Window x:Class="WpfTutorialSamples.WPF_Application.ResourcesFromCodeBehindSample"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:sys="clr-namespace:System;assembly=mscorlib"Title="ResourcesFromCodeBehindSample" Height="175" Width="250"><Window.Resources><sys:String x:Key="strWindow">Hello, Window world!</sys:String></Window.Resources><DockPanel Margin="10" Name="pnlMain"><DockPanel.Resources><sys:String x:Key="strPanel">Hello, Panel world!</sys:String></DockPanel.Resources><WrapPanel DockPanel.Dock="Top" HorizontalAlignment="Center" Margin="10"><Button Name="btnClickMe" Click="btnClickMe_Click">Click me!</Button></WrapPanel><ListBox Name="lbResult" /></DockPanel>
</Window></span>

Code-behind:

<span style="font-size:14px;">using System;
using System.Windows;namespace WpfTutorialSamples.WPF_Application
{public partial class ResourcesFromCodeBehindSample : Window{public ResourcesFromCodeBehindSample(){InitializeComponent();}private void btnClickMe_Click(object sender, RoutedEventArgs e){lbResult.Items.Add(pnlMain.FindResource("strPanel").ToString());lbResult.Items.Add(this.FindResource("strWindow").ToString());lbResult.Items.Add(Application.Current.FindResource("strApp").ToString());}}
}</span>

我们将 "Hello, world!" 放在三个不同的地方:App.xaml、窗口内部、本地panel。界面包含一个按钮和一个listbox。

在后台代码,我们处理按钮的点击事件,将三个不同地方的 "Hello, world!" 添加到ListBox中,如截屏所示。我们使用了FindResource()方法,将资源作为一个对象返回,然后用ToString()方法转换成字符串。
注意在FindResource()里,先访问panel,然后是窗口,最后是当前的应用对象。这对于寻找已知位置的资源非常有用。但是,如前面所述,如果资源找不到,那么会向上层搜索。所以原则上我们可以使用FindResource()在panel里访问三个地方,如果没有就会继续去窗口继而去应用层搜索。
反过来会怎么样呢?就不对了,你不能在窗口或者本地控件定义了资源,然后从应用层开始访问。

WPF教程(十二)资源相关推荐

  1. 【Visual C++】游戏开发笔记四十四 浅墨DirectX教程十二 网格模型和X文件使用面面观

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhmxy555/article/details/8586540 作者:毛星云(浅墨 ...

  2. 【Visual C++】游戏开发笔记四十四 浅墨DirectX教程十二 网格模型和X文件使用面面观...

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接:http://blog.csdn.net/zhmxy555/article/details/8586540 作者:毛星云(浅墨) ...

  3. PyQt5教程(十二)——实现QQ登录界面(六、实现鼠标拖动界面,鼠标事件)

    PyQt5教程(十二)--实现QQ登录界面(五.实现鼠标拖动界面,鼠标事件) 一.实现界面可以随着鼠标进行拖动 1.主要就是对鼠标事件的实现: def mousePressEvent(self, ev ...

  4. Wix 安装部署教程(十二) -- 自动更新WXS文件

    原文:Wix 安装部署教程(十二) -- 自动更新WXS文件 上一篇分享了一个QuickWIX,用来对比两个工程前后的差异,但是这样还是很繁琐,而且昨天发现有Bug,目录对比有问题.这次改变做法,完全 ...

  5. VML极道教程(十二) VML编程大结局

    本系列文章导航 VML极道教程(一) VML介绍 VML极道教程(二) VML入门 VML极道教程(三) 标记实战与line线 VML极道教程(四) oval圆rect矩型 VML极道教程(五) Ro ...

  6. twisted系列教程十二–为server 增加一个service

    One More Server 在第九部分和第十部分我们介绍了关于诗歌的变形引擎的想法,最后我们实现了cummingsifier,我们还让它抛出随机的异常来模拟错误.但是假如这个变形的引擎在另外一台服 ...

  7. nCode:DesignLife案例教程十二

    nCode:DesignLife 案例十二--Virtual Strain Gauge Correlation 12.1 案例文件 12.2 背景 12.3 创建流程 12.4 保存虚拟应变计 12. ...

  8. WPF教程(二十四)Canvas

    Canvas大概是最简单的面板了.在默认情况下,它什么都不做,你把控件放到它里面,然后通过具体的坐标来指定位置. 如果你之前使用过其他UI库如WinForms,Canvas会让你感觉很亲切.然而它趋向 ...

  9. WPF教程(二十)密码框

    WPF中编辑常规的文字都是使用文本框,但是如果是输入密码呢?功能应该是一样的,但是我们不想周边的人看着我们一个字母一个字母的输入,这样密码就被泄漏了,因此我们想用别的字符来替代真实密码的显示.出于这个 ...

  10. WPF教程(二十五)WrapPanel

    WrapPanel用于一个接一个的排列子控件,以水平或者垂直方向,当空间不足时就会自动切换到下一行.适合于需要水平或者垂直排列控件且能自动换行的情况. 水平方向排列时,每一行所有子控件的高度都被统一成 ...

最新文章

  1. C语言指针表示二维数组的方法!_只愿与一人十指紧扣_新浪博客
  2. Mac os x下配置nginx + php
  3. docker和java容器_使用Docker容器和Java EE进行持续交付
  4. 虚拟机中安装linux
  5. 看看这帮猴子的伪原创工具
  6. Mac 打开jupyter
  7. gpt efi win7 linux,在EFI+GPT硬盘上利用grub2实现Linux/Win7/win8等多重启动
  8. Spark基础学习笔记06:搭建Spark On YARN模式的集群
  9. LINQ to Objects和多线程实现文件查找与分组
  10. 使用 Vi/Vim 编辑器:基础篇
  11. 测试TF card 的读写速度
  12. Python函数的输出
  13. oracle数据库修改密码方法,修改oracle数据库用户名及密码的方法
  14. 抖音网页版上线:这回可以在电脑上刷抖音啦!
  15. NetSuite 巧做打印模板
  16. energy plus matlab,Energyplus教程系列1—Energyplus到底能干啥.ppt
  17. 游戏研发人才学校培养、企业需求与个人快速成长,华科校友分享了这些实用观点
  18. 网易2017校招合唱团
  19. 计算机毕业设计Java移动垃圾分类车管理平台(源码+系统+mysql数据库+Lw文档)
  20. 年礼成快递企业不再接件主因:苹果产品最疯狂

热门文章

  1. 微信小程序获取手机号登录流程
  2. .NET 中的程序集
  3. 编译原理--实验2 语法分析
  4. mysql 商品规格表_商品规格分析
  5. 自建服务器同步软件,黑群晖自建anki服务器电脑anki软件设置同步
  6. 取消打印机选择框实现
  7. 2018.08.21 bzoj4668: 冷战(并查集+启发式合并)
  8. Wps日期时间格式转文本、科学计数法转数字
  9. 我把跨境电商当副业 ,一周赚了7000块:想给有梦想的人提个醒 !
  10. 用计算机写文章 单元备课,备课写教案