zoukankan      html  css  js  c++  java
  • DynamicResource与StaticResource的区别

    下面用例子更详细地说明DynamicResource与StaticResource的区别。

    先看看这段XAML代码:
    // LinearGradientBrush.xaml
    <Window x:Class="BrawDraw.Com.LinearGradientBrush.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="LinearGradientBrush" Height="300" Width="300">
        <Canvas Background="{DynamicResource innerLgbResource}">
            <Canvas.Resources>
                    <LinearGradientBrush StartPoint="0,0" EndPoint="0,1" x:Key="innerLgbResource">
                        <GradientStop Color="Yellow" Offset="0.0" />
                        <GradientStop Color="Orange" Offset="0.5" />
                        <GradientStop Color="Red" Offset="1" />
                    </LinearGradientBrush>
            </Canvas.Resources>
        </Canvas>
    </Window>
    注意:innerLgbResource是基于Yellow, Orange, Red三种颜色的渐变。

    相应的cs文件:
    // LinearGradientBrush.xaml.cs
    using System;
    using System.Windows;

    namespace BrawDraw.Com.LinearGradientBrush
    {
        /// <summary>
        /// Interaction logic for Window1.xaml
        /// </summary>
        public partial class Window1 : Window
        {
            public Window1()
            {
                InitializeComponent();
            }
        }
    }
    运行的效果:
    使用元素内部的动态资源
    图1

    注意XAML代码中的这句:<Canvas Background="{DynamicResource innerLgbResource}">,Canvas的背景使用了动态资源。
    如果你将它改为<Canvas Background="{StaticResource innerLgbResource}">,将会收到错误提示:“StaticResource reference 'innerLgbResource' was not found.”
    出现此问题的原因是:StaticResource 查询行为不支持向前引用,即不能引用在引用点之后才定义的资源
    DynamicResource可以向前引用,即DynamicResource运行时才查找并加载所定义的资源。

    接下来我们来“变变花样”。
    先在App.xaml中加入应用程序级资源:
    <Application x:Class="BrawDraw.Com.LinearGradientBrush.App"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        StartupUri="LinearGradientBrush.xaml">
        <Application.Resources>
            <LinearGradientBrush StartPoint="0,0" EndPoint="0,1" x:Key="appLgbResource">
                <GradientStop Color="Beige" Offset="0.0" />
                <GradientStop Color="Red" Offset="0.3" />
                <GradientStop Color="Yellow" Offset="0.5" />
                <GradientStop Color="Green" Offset="0.75" />
                <GradientStop Color="Orange" Offset="1" />
            </LinearGradientBrush>
            <Style TargetType="Canvas">
                <Setter Property="Background" Value="{StaticResource appLgbResource}">
                </Setter>
            </Style>
        </Application.Resources>

    </Application>
    注意<Application.Resources>...</Application.Resources>之间的部分。这里使用了从Beige, Red, Yellow, Green到Orange五种颜色的渐变。同时,将Canvas的背景属性使用Style/Setter的方式设置为这五种给定的渐变色。由于此五种颜色是一次性设置,之后不再改变,所以使用了StaticResource。

    [讨论]
    可以使用DynamicResource吗?
    比如:<Setter Property="Background" Value="{DynamicResource appLgbResource}">
    答案是:可以!

    然后将LinearGradientBrush.xaml中<Canvas Background="{DynamicResource innerLgbResource}">这句改成:
    <Canvas Background="{StaticResource appLgbResource}">,运行结果:
    应用程序级资源
    图2

    接着试验:
    (1)将<Canvas Background="{StaticResource appLgbResource}">改成:<Canvas Background="{DynamicResource appLgbResource}">试试,效果与图2一样!
    (2)将<Canvas Background="{...}">中Background属性去掉,改成:<Canvas>,运行效果也与图2一致。
    (3)如果改成:<Canvas Background="{DynamicResource innerLgbResource}">时,则显示图1所示基于基于Yellow, Orange, Red三种颜色的渐变效果。
    (4)你甚至可以这样:
    App.xml中使用<Setter Property="Background" Value="{DynamicResource appLgbResource}">,而在LinearGradientBrush.xaml中使用<Canvas Background="{StaticResource appLgbResource}">(运行效果如图2)。

    探讨:
    1、当引用资源时,选择StaticResource还是DynamicResource的考虑因素:
    (1)在哪里创建资源?(资源的范围或层级
    a. 资源是在一个Page/Canvas/Window中?
    b. 在应用程序范围中?
    c. 在松散的Xaml中?
    d. 在某个特定的Object(比如某个特定的Button)中?
    物件级:此时,资源只能套用在这个Object物件,或套用至该物件的子物件。 
    文件级:如果将资源定义在Window或Page层级的XAML档中,那么可以套用到这个文件中的所有物件。 
    应用程序级:如果我们将资源定义在App.xaml 中,那么,就可以将资源套用到应用程序内的任何地方。 
    字典级:当我们把资源封装成一个资源字典, 定义到一个ResourceDictionary的XAML文件时,就可以在另一个应用程序中重复使用。

    (2) 应用程序的功能:是否在运行时改变资源?
    如果需要改变,则使用DynamicResource。
    (3) 每个资源引用类型不同的寻找行为。(需要支持向前引用吗?)

    StaticResources的适用场合:
    (1)在资源第一次引用之后无需再修改资源的值。
    (2)资源引用不会基于运行时的行为进行重新计算,比如在重新加载Page/Window的时候。
    (3)当需要设置的属性不是DependencyObject或Freezable类型的时候,用StaticResource。
    (4)当需要将资源编译到dll中,并打包为程序的一部份,或者希望在各应用程序之间共享时,也使用StaticResource。
    (5)当需要为一个自定义控件创建一个Theme,并Theme中使用资源,就需要使用StaticResource。因为StaticResource的资源查找行为时可预测的,并且本身包含在Theme中。而对于DynamicResource,即使资源是定义在Theme中,也只能等到运行时确定,导致一些可能意料不到的情况发生。
    (6)当需要使用资源设置大量的依赖属性(Dependency Property)的时候。
    由于依赖属性具有属性系统提供的值缓存机制,所以,如果能在程序装载时设置依赖属性的值,这样,依赖属性就不需要检查自己的值并返回最后的有效值了。
     
    Dynamic Resource一般使用在如下场合:
    (1)资源的值依赖一些条件,而该条件直到运行时才能确定。
    包括系统资源,或是用户可设置的资源。比如:可以创建引用系统属性诸如SystemColors,SystemFonts来设置值,而这些属性是动态的,它们的值又来自于运行环境和操作系统。
    (2)为自定义控件引用或创建Theme Style。
    (3)希望在程序运行期间调整资源字典的内容时。
    (4)希望资源可以向前引用时(如上面在Canvas中引用innerLgbResource一样)
    (5)资源文件很大,希望在运行时才加载。
    (6)要创建的Style的值可能来自于其它值,而这些值又依赖于Theme或用户的设置。
    (7)当引用资源的元素的父元素有可能在运行期改变,这个时候也需要使用动态资源。因为父元素的改变将导致资源查询的范围。
    Dynamic resource的限制条件:属性必须是依赖属性,或是Freezable的。

    资源的查询方式
    Static Resource的查询
    (1)查找使用该资源的元素的Resource字典;
    (2)顺着逻辑树向上查找父元素的资源字典,直到根节点;
    (3)查找Application资源;
    (4)不支持向前引用,即:不能引用在引用点之后才定义的资源。

    Dynamic Resource的查询
    (1)查找使用该资源的元素的Resource字典;
    如果元素定义了一个Style 属性,将查找Style中的资源字典;如果元素定义了一个Template属性,将查找FrameworkTemplate中的资源字典。
    (2)顺逻辑树向上查找父元素的资源字典,直到根节点;
    (3)查找Application资源;
    (4)查找当前激活状态下的Theme资源字典;
    (5)查找系统资源。

  • 相关阅读:
    C#_获取汉字拼音
    C#中汉字轻松得到拼音全文类
    Mvc利用淘宝Kissy uploader实现图片批量上传附带瀑布流的照片墙
    ASP.NET的用户控件
    js获取url参数值
    常用编程软件下载地址
    Asp.net 程序优化js,css合并与压缩
    做BS开发,你应该知道的一些东西
    c#.net常用函数和方法集
    C# Lambda Expressions 简介
  • 原文地址:https://www.cnblogs.com/gylhaut/p/5287959.html
Copyright © 2011-2022 走看看