静态资源(StaticResource)和动态资源(DynamicResource)

资源可以作为静态资源或动态资源进行引用。这是通过使用 StaticResource 标记扩展或 DynamicResource 标记扩展完成的。

StaticResource 通过替换已定义资源的值来为 XAML 属性提供值。

DynamicResource 通过将值推迟为对资源的运行时引用来为XAML 属性提供值。动态资源引用强制在每次访问此类资源时都重新进行查找。

通常来说,不需要在运行时更改的资源使用静态资源;而需要在运行时更改的资源使用动态资源。动态资源需要使用的系统开销大于静态资源的系统开销。例如以下的例子:

   1: <Window x:Class="WPFResource.StaticAndDynamicResource"
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:     Title="StaticAndDynamicResource" Height="200" Width="300">
   5:     <Window.Resources>
   6:         <SolidColorBrush x:Key="ButtonBrush" Color="Red" />
   7:     </Window.Resources>
   8:     
   9:     <StackPanel>
  10:         <Button Margin="5" Content="Static Resource Button A" Background="{StaticResource ButtonBrush}" />
  11:         <Button Margin="5" Content="Static Resource Button B" Background="{StaticResource ButtonBrush}">
  12:             <Button.Resources>
  13:                 <SolidColorBrush x:Key="ButtonBrush" Color="Yellow" />
  14:             </Button.Resources>
  15:         </Button>
  16:         <Button Margin="5" Content="Change Button Resource" Click="Button_Click" />
  17:         <Button Margin="5" Content="Dynamic Resource Button A" Background="{DynamicResource ButtonBrush}" />
  18:         <Button Margin="5" Content="Dynamic Resource Button B" Background="{DynamicResource ButtonBrush}">
  19:             <Button.Resources>
  20:                 <SolidColorBrush x:Key="ButtonBrush" Color="Yellow" />
  21:             </Button.Resources>
  22:         </Button>
  23:     </StackPanel>
  24: </Window>
   1: private void Button_Click(object sender, RoutedEventArgs e)
   2: {
   3:     SolidColorBrush brush = new SolidColorBrush(Colors.Green);
   4:     this.Resources["ButtonBrush"] = brush;
   5: }

以上的例子在运行时显示如下:

而点击“Change Button Resource”按钮后,显示的结果为:

从程序执行的结果来看,我们可以得到如下的结论:

  • 静态资源引用是从控件所在的容器开始依次向上查找的,而动态资源的引用是从控件开始向上查找的(即控件的资源覆盖其父容器的同名资源)
  • 更改资源时,动态引用的控件样式发生变化(即"Dynamic Resource Button A"发生变化)

如果要更改"Dynamic Resource Button B"的背景,需要在按钮的事件中添加以下代码(将"Dynamic Resource Button B"的控件的x:Name设置为"btn4")

   1: SolidColorBrush brushB = new SolidColorBrush(Colors.Blue);
   2: this.btn4.Resources["ButtonBrush"] = brushB;

执行的结果如下:

静态资源引用最适合于以下情况:

  • 您的应用程序设计几乎将所有的应用程序资源集中到页或应用程序级别的资源字典中。静态资源引用不会基于运行时行为(例如重新加载页)进行重新求值,因此,根据您的资源和应用程序设计避免大量不必要的动态资源引用,这样可以提高性能。

  • 您正在设置不在 DependencyObject 或 Freezable 上的属性的值。

  • 您正在创建将编译为 DLL 并打包为应用程序的一部分或在应用程序之间共享的资源字典。

  • 您正在为自定义控件创建一个主题,并定义在主题中使用的资源。对于这种情况,通常不需要动态资源引用查找行为,而需要静态资源引用行为,以使该查找可预测并且独立于该主题。使用动态资源引用时,即使是主题中的引用也会直到运行时才进行求值,并且在应用主题时,某个本地元素有可能会重新定义您的主题试图引用的键,并且本地元素在查找中会位于主题本身之前。如果发生该情况,主题将不会按预期方式运行。

  • 您正在使用资源来设置大量依赖项属性。依赖项属性具有由属性系统启用的有效值缓存功能,因此,如果您为可以在加载时求值的依赖项属性提供值,该依赖项属性将不必查看重新求值的表达式,并且可以返回最后一个有效值。该方法具有性能优势。

  • 您需要为所有使用者更改基础资源,或者需要通过使用 x:Shared 属性为每个使用者维护独立的可写实例。

动态资源最适合于以下情况:

  • 资源的值取决于直到运行时才知道的情况。这包括系统资源,或用户可设置的资源。例如,您可以创建引用由 SystemColors、SystemFonts 或 SystemParameters 公开的系统属性的 setter 值。这些值是真正动态的,因为它们最终来自于用户和操作系统的运行时环境。您还可以使用可以更改的应用程序级别的主题,在此情况下,页级别的资源访问还必须捕获更改。

  • 您正在为自定义控件创建或引用主题样式。

  • 您希望在应用程序生存期调整 ResourceDictionary 的内容。

  • 您有一个存在依存关系的复杂资源结构,在这种情况下,可能需要前向引用。静态资源引用不支持前向引用,但动态资源引用支持,因为资源直到运行时才需要进行求值,因此,前向引用不是一个相关概念。

  • 从编译或工作集角度来说,您引用的资源特别大,并且加载页时可能无法立即使用该资源。静态资源引用始终在加载页时从 XAML 加载;而动态资源引用直到实际使用时才会加载。

  • 您要创建的样式的 setter 值可能来自受主题或其他用户设置影响的其他值。

  • 您正在将资源应用到元素,而在应用程序生存期中可能会在逻辑树中重新设置该元素的父级。更改此父级还可能会更改资源查找范围,因此,如果您希望基于新范围对重新设置了父级的元素的资源进行重新求值,请始终使用动态资源引用。

不同类型的资源

1、程序集资源。这种常见于将图片设定到程序集中,做为程序集的资源。

程序集资源在定义时,将文件复制到解决方案-项目所在的目录或其子目录中,并将文件的属性中的Build Action设置为Resource。(注意,WPF不支持项目属性中的资源)

然后在XAML文件中使用如Image的Source属性,指定到此文件:

   1: <StackPanel Background="#FFC7DAFF">
   2:     <TextBlock Margin="5" Text="Assembly Resource" />
   3:     <Image Margin="5" Source="Image/Users.png" Width="32" Height="32" />
   4:     <Button Margin="5">
   5:         <Button.Content>
   6:             <StackPanel Orientation="Horizontal">
   7:                 <Image Margin="5" Source="Image/Users.png" Width="32" Height="32" />
   8:                 <TextBlock Text="My Button" VerticalAlignment="Center" />
   9:             </StackPanel>
  10:         </Button.Content>
  11:     </Button>
  12: </StackPanel>

此项目编译后,在Assembly中将封装该图片文件。此种方法适用于较小的资源。

2、对象资源

除刚刚我们使用的图片做为程序集资源外,前面例子中所使用的资源均是对象资源。系统对于对象资源使用ResouceDictionary这个字典集合处理,其Key对应即x:Key声明的键,Value对应资源。我们前面使用的都是SolidColorBrush对象,再例如使用字符串及ImageBrush对象做为资源:

   1: <StackPanel Background="#FFE6FDC8">
   2:     <StackPanel.Resources>
   3:         <c:String x:Key="strMessage">My String Value.</c:String>
   4:         <ImageBrush x:Key="imgBrush" ImageSource="Image/Users.png"
   5:                     ViewportUnits="Absolute" Viewport="0 0 32 32"/>
   6:     </StackPanel.Resources>
   7:     <TextBlock Margin="5" Text="Object Resource" />
   8:     <TextBox Margin="5" Text="{StaticResource strMessage}" />
   9:     <Button Margin="5" Height="32" HorizontalContentAlignment="Right" 
  10:             Content="{StaticResource strMessage}" 
  11:             Background="{StaticResource imgBrush}" Width="125" />
  12: </StackPanel>

程序执行结果为:

静态资源(StaticResource)和动态资源(DynamicResource)的更多相关文章

  1. [WPF]静态资源(StaticResource)和动态资源(DynamicResource)

    一.文章概述 本演示介绍WPF基本采用静态和动态的资源.而且两者都做一个简单的比较. 静态资源(StaticResource)指的是在程序加载内存时对资源的一次性使用,之后就不再訪问这个资源了:动态资 ...

  2. WPFの静态资源(StaticResource)和动态资源(DynamicResource)

    下面是前台代码: <Window.Resources>        <TextBlock x:Key="res1" Text="好好学习"/ ...

  3. 静态资源(StaticResource)和动态资源(DynamicResource)

    一.文章概述 本演示介绍了WPF的静态资源和动态资源的基本使用,并对两者做了简单的比较. 二.定义并使用资源 <Window x:Class="Demo010.MainWindow&q ...

  4. zzy:请求静态资源和请求动态资源, src再次请求服务器资源

    [总结可以发起请求的阶段:请求动态资源:通过web.xml匹配action然后,自定义Servlet处理该action1)form表单提交请求的时候,用action设定,该页面发起请求的Servlet ...

  5. servlet基本原理(手动创建动态资源+工具开发动态资源)

    一.手动开发动态资源 1 静态资源和动态资源的区别 静态资源: 当用户多次访问这个资源,资源的源代码永远不会改变的资源. 动态资源:当用户多次访问这个资源,资源的源代码可能会发送改变. <scr ...

  6. WPF基础篇之静态资源和动态资源

    静态资源(StaticResource)指的是在程序载入内存时对资源的一次性使用,之后就不再访问这个资源了. 动态资源(DynamicResource)指的是在程序运行过程中然会去访问资源. 一.定义 ...

  7. wpf中静态资源和动态资源的区别

    静态资源(StaticResource)指的是在程序载入内存时对资源的一次性使用,之后就不再访问这个资源了. 动态资源(DynamicResource)指的是在程序运行过程中然会去访问资源.

  8. 0055 <mvc:default-servlet-handler />不能同时访问静态资源和动态资源的问题

    刚才在折腾的时候,发现applicationContext.xml中配置了<mvc:default-servlet-handler />后,能访问静态资源,却不能访问动态资源了:注释掉之后 ...

  9. WPF 资源(StaticResource 静态资源、DynamicResource 动态资源、添加二进制资源、绑定资源树)

    原文:WPF 资源(StaticResource 静态资源.DynamicResource 动态资源.添加二进制资源.绑定资源树) 一.WPF对象级(Window对象)资源的定义与查找 实例一: St ...

随机推荐

  1. ActiveMQ-如何使用JMS API?

    JMS编程模型 JMS定义了Java中访问消息中间件的一组接口,主要包括ConnectionFactory.Connection.Session.Destination.MessageProducer ...

  2. Java的BIO,NIO,AIO

    Java中的IO操作可谓常见.在Java的IO体系中,常有些名词容易让人困惑不解.为此,先通俗地介绍下这些名词. 1 什么是同步? 2 什么是异步? 3 什么是阻塞? 4 什么是非阻塞? 5 什么是同 ...

  3. modprobe

    1.1 简介 Linux命令:modprobe .功能说明:自动处理可载入模块.语 法:modprobe [-acdlrtvV][--help][模块文件][符号名称 = 符号值].补充说明:modp ...

  4. python爬取漫画

    抓取漫画的网址是:sf互动传媒 抓取漫画的由来也是看了知乎上有人说用爬取漫画,然后自己也玩玩 首页中每个漫画的url是类似这样存储的: <tr> <td height="3 ...

  5. Python+Selenium 自动化实现实例-单元测试报告

    代码如下: # -*- coding: utf-8 -*- from selenium import webdriver import unittest,time import HTMLTestRun ...

  6. STM32 磁场传感器HMC5883

    一.IIC协议 默认(出厂) HMC5883LL 7 位从机地址为0x3C 的写入操作,或0x3D 的读出操作. 要改变测量模式到连续测量模式,在通电时间后传送三个字节:0x3C 0x02 0x00 ...

  7. 关于Android不同系统版本的市场占比情况详解

    一,google官方统计的不同Android版本市场的占比强开 google统计的数据情况 这个是google官方对于不同版本的市场占比情况.这个是针对全世界所有的Android手机占比情况. 二,友 ...

  8. centos使用boost过程

    1. 安装gcc,g++,make等开发环境 yum groupinstall "Development Tools" 2. 安装boost  yum install boost ...

  9. openCV训练程序申请内存不足

     openCV训练程序申请内存不足   在用OpenCV训练分类器(特别是训练Adaboost类型的分类器)的时候,当样本的数量特别大的时候,就会出现申请内存不够的情况,很早以前碰到过这样的情况,最近 ...

  10. lr场景运行报错的解决方法