闲话WPF之十六(WPF中的资源 [2])

在本系列的之十三中简单介绍了WPF中资源的资源。但是,没有给出任何具体的实例,在这个Post中将给出一个动态资源的例子,也算是响应daxian110的请求。并适当的扩展在前一个Post当中没有涉及的知识。

我们先看一个例子程序:

<Window x:Class="WindowsApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="WindowsApplication1" Height="150" Width="100" Loaded="OnLoaded"
    >
    <Canvas>
      <Button Click="OnClick" Canvas.Left="10" Canvas.Top="20"
              Width="80" Height="30" Content="{DynamicResource TestRes1}"/>
      <Button Canvas.Left="10" Canvas.Top="60" Width="80"
              Height="30" Content="{DynamicResource TestRes2}"/>
    </Canvas>
</Window>

程序很简单,在窗口中添加了两个按钮,我们需要关注的是其中对Content属性。这个属性的作用就是设置按钮的内容。为什么这里的名称不是Text,而是Content?如此命名的原因和WPF中控件一个非常重要的概念有关:WPF中几乎任何的控件(也就是Element)都可以作为一个容器存在。也就是说我们在Content属性中可以包含其它任何你想显示的内容。不止是字符串文本。这种抽象的处理使我们可以把所有的内容等同对待,减少了很多处理上的麻烦。在本例子中,Content属性被和一个TestRes1和TestRes2关联起来。这个TestRes到底是什么呢?这就是动态资源的名称。具体的内容在显示按钮的时候决定。

注意上面Window中的Loaded属性,通过它我们可以设置一个函数名称,它将Window加载完成后被调用。下面就看看如何用代码控制TestRes:

private void OnLoaded(object sender, RoutedEventArgs e)
{
      string szText1 = "Res Text1";
      this.Resources.Add("TestRes1", szText1);

      string szText2 = "Res Text2";
      this.Resources.Add("TestRes2", szText2);
}

OnLoaded是Window1类中的一个成员函数,在这个函数里,我们需要添加资源,因为我们的XAML中需要使用TestRes1和TestRes2,运行时如果找不到对应资源,程序将失败。

现在,我们调用Add方法添加资源。第一个参数是资源的名称,第二个参数是添加的资源对象。

程序的运行效果如图1:

                  
      图1                                                图2

接下来我们看看修改资源的方法。在上面XAML的第一个按钮的Click属性中我们指定了一个OnClick事件方法。它将在点击按钮时调用,现在我们通过这个事件来修改另一个按钮的Content资源:

private void OnClick(object sender, RoutedEventArgs e)
{
      string szText = "New Res Text";
      this.Resources.Remove("TestRes2");
      this.Resources.Add("TestRes2", szText);
}

OnLoaded实现同样的简单,先调用Remove方法删除已有的TestRes2资源,然后重新添加一个新的TestRes2资源对象。点击第一个按钮后,下面按钮的文本将自动修改为新的资源对象。运行效果如图2。 

XAML加载器在分析XAML文件时,发现StaticResource,将会在当前Element的资源中查找指定的Key,如果查找失败,将沿着逻辑树向上查找,直到Root元素。如果还没有找到资源,再查找Application下定义的资源。在Application中定义的资源适用于整个应用程序。类似于全局对象。注意:使用Static资源时,不能向前引用。即使偶尔程序运行成功,向前引用的效率将非常低,因为它需要查找所有的ResourceDictionay。对于这种情况,使用DynamicResource将更适合。

另一方面,XAML加载器发现DynamicResource时,将根据当前的属性设置创建一个表达式,直到运行过程中资源需要,才根据表达式从资源中查找相关内容进行计算,返回所需的对象。注意,DynamicResource的查找于StaticResource基本类似,除了在定义了Style和Template时,会多一个查找目标。具体的细节可参数MSDN。

posted @ 2006-12-30 21:00 赖仪灵 阅读(3177) 评论(12)  编辑 收藏 网摘 所属分类: WPF

  回复  引用    
#1楼2006-12-30 21:53 | ml80[未注册用户]
谢谢分享!
  回复  引用  查看    
#2楼[楼主]2006-12-30 22:16 | Yiling Lai      
@ml80

客户啦!

  回复  引用  查看    
#4楼2006-12-31 10:09 | daxian110      
谢谢楼主的文章!
关于这两种资源的使用,我有一点疑问:是不是Static资源只能在.xaml文件中定义,Dynamic资源只能在.cs文件中定义?如果这样的话,使用Dynamic资源时.xaml文件和.cs文件的耦合比使用Static资源要大,真有一天这两种文件由美工和程序员分别编写时,程序运行的风险也大。个人愚见,还请望指教!

  回复  引用  查看    
#5楼[楼主]2006-12-31 10:36 | Yiling Lai      
@daxian110

Dynamic资源可以在XAML文件中定义!注意的区别在于我们使用资源时所用的标记扩展是StaticResource还是DynamicResourcez。而且资源还可以定义在单独的文件中,这样方便实现应用程序的本地化

  回复  引用  查看    
#6楼2006-12-31 11:50 | daxian110      
@Yiling Lai

在 闲话WPF之十三(WPF中的资源)这篇文章提到的例子中,我曾试过把其中使用资源时的StaticResource标示符改成DynamicResource,运行效果是一样,这是不是意味着:虽然程序看上去运行结果一样,但是内部使用资源的机制已发生变化?

  回复  引用  查看    
#7楼[楼主]2006-12-31 12:06 | Yiling Lai      
@daxian110

对的,运行效果一样,但是加载方式已经不同了!使用的机制也变了,正如我在这个Post最后所说的那样!

  回复  引用  查看    
#8楼2006-12-31 13:07 | daxian110      
@Yiling Lai

非常感谢!

  回复  引用    
#9楼2007-11-07 21:19 | 丰心[未注册用户]
多谢楼主了,找到这种资料太高兴了,现在网上这wpf的资料太少了。非常感谢。
  回复  引用  查看    
#10楼2008-05-22 01:58 | 水言木      
同样非常感谢楼主的文章,虽然我是在您发表了两年之后才看到它
  回复  引用  查看    
#11楼2009-06-29 17:19 | 李迪      
呵呵,三年后,我才看到,真是落后了啊。

呵呵




发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 608237




相关文章:

相关链接: