我们都知道在WPF中,所有的控件都有Resources属性,里面可以放Resource。一般比较常用的Resource位置就是Application的Resource和各个Window的Resource。那么这两个Resource的位置,除了作用范围不同之外,还有什么不同呢?

一个不同点就是,Application的Resource会被作用一个全局共享的Resource的来源。这会给Merge Resource Dictionary带来极大的方便,但是这个性质并不像想象中的那么好用。

在实际项目中,通常会对Resource的使用有如下的几点要求。

1.       不要把所有的Resource放在一个文件里。我们常常会把Resource按其功能或是使用对象,分别放置在不同的Resource Dictionary里,这样不仅结构清楚,找起来方便,而且用Blend打开时也会更快,共同开发的冲突也会更少。

2.       使用Resource时,出于性能考虑,要尽量使用StaticResource。这个要求,会间接地要求Resource按顺序定义,就是说,未定义过的Resource是不能使用的。而XAML中又不存在类似C语言中的声明语句或是头文件。这样Resource就必须非常注意其顺序。一不小心就会出现NotFindException.

当把上面的两个要求合并起来之后,问题会变得很复杂。由于Resource放在了不同的Resource文件中,这就要考虑到Resource的跨文件引用问题。这个问题有两个解决方案。

1.       如果Resource文件A,使用了Resource文件B中的Resource,那么就在文件A中,通过ResourceDictionary.MergedResourceDictionaries把Resource文件B合并过来。这个方式的一个问题就是,要为每个文件维护一个依赖文件列表,而且如果有多个Resource文件Merge了同一个Resource文件,会给人一种冗余的感觉。是不是这个被Merge了多次的Resource文件,相当于有了多件拷贝?

2.       另一种方式就是在Application的Resource中把所有的Resource文件都Merge进来。而且要一个一个Merge。这样,下面的MergedResource就可以访问上面的MergedResource里的东西了。而且只有直接在Application的Resource里这样写才有效果。

MergeResource的示例如下。用代码会更直观一些。

View Code

ResourceDictionary>    <ResourceDictionary.MergedDictionaries>        <ResourceDictionary Source="CommonProperties.xaml"/>        <ResourceDictionary Source="Button.Style.xaml"/>        <ResourceDictionary Source="ComboBox.Style.xaml"/>    </ResourceDictionary.MergedDictionaries></ResourceDictionary>

在上面的示例中,如果XXXX.Style.xaml中的Resource以Static的方式使用了CommonProperties.xaml里的Resource有如下图所示的引用关系。

图1. Resource间的引用关系示例

那么这样的Merge Resource方式,能否保证XXXX.Style.xaml能够引用到CommonProperties.xaml里的Resource呢?答案是不一定,要看这个MergeResource的代码放置在了什么地方,如果是在App.xaml里,可以;如果不是,则不可以。

如下图所示。

图2. 可行的Merge方式(直接在Application的Resource里Merge)

图3. 不可行的Merge方式。(在单独的一个文件里Merge)

图4. 亦不可行的方案(在Window中Merge)

所以在WPF程序中,应该尽量在App.xaml进行Resource的Merge工作。但是这也造成了一些问题。如DLL封装性的问题——专门存放Resource的DLL,不能通过一个已经Merge好的,单一的Resource文件把这个DLL里的所有Resource暴露给使用者,使用者必须在App.xaml里一个一个地引用DLL中的所有Resource文件,DLL改了,App.xaml的引用也要改,从而破坏了封装性。再一个问题就是如果没有WPF Application(比如在WinForm程序中集成一些WPF的组件),那就可能会没有Application级的Resource,也就没有很好的Merge Resource的解决方案了。可行的方案有四个。

1.       建立一个WPF Application,并Host原来程序中的WinForm部分。而不是在WinForm程序里Host WPF组件。

2.       把所有Resource放在一个文件里,并维护好Resource的前后顺序,这样就没有了文件间的引用问题。

3.       为每个Resource文件都使用MergedResourceDictionary。把它用到的Resource文件Merge进来。这个方案可能会造成Resource重复的问题。

4.       退一步。对于文件间的引用使用DynamicResource。有人认为DynamicResource比StaticResource的性能差,我同意。经过测试,DynamicResource用的时间是StaitcResource的5倍。但是如果Resource不会变,那只不过是在第一次加载时慢些罢了。还是在真正有性能问题的地方下功夫吧。

这个只能在Application里Merge Resource File的事实,也许可以算是一个Bug吧,因为从WPF的使用者的角度而言,总是希望无论这个Merge在什么地方,都可以保证Resource文件的向上引用才好。

转载于:https://www.cnblogs.com/junbird-nest/archive/2012/03/06/2382473.html

多Resource文件的相互引用与合并问题及其解决方案相关推荐

  1. 毕业设计出现的一个严重错误----文件不能相互引用

    昨晚大概1点,突然点某几个链接,出现了"你指定的网站不能访问,链接错误"这样的情况,然点击其它的网页却没有错误,一段时间极度郁闷,知道1点半没弄出来 今天下午经过一番删除测试,终于 ...

  2. php文件之间相互引用路径问题的一般处理方法

    在其他web编程语言中相对路径都是以当前处理文件目录为基准,而在php中并非如此.php中相对路径是以当前工作目录为基准的,并非以当前处理文件目录为基准,这样在开发过程中带来了不少的麻烦.比如会遇到一 ...

  3. stack - all - 有道云笔记内部文件如何相互引用

    世界上并没有完美的程序,但是我们并不因此而沮丧,因为写程序就是一个不断追求完美的过程. 选中笔记文件 -> 点击鼠标右键 -> 复制引用链接 选中指定位置 -> 点击鼠标右键 -&g ...

  4. go语言中同一个package下的文件相互引用怎么做?

    go语言中同一个package下的文件相互引用怎么做? go 里面一个目录为一个package, 一个package级别的func, type, 变量, 常量, 这个package下的所有文件里的代码 ...

  5. C 语言 具有从属关系的结构体分别在不同头文件相互引用的问题

    目录 一.说明 二.例子 一.说明 给定头文件 father.h, son.h, daughter.h, son.h 和 daughter.h 里有各自的结构体,而 father.h 里有结构体囊括了 ...

  6. 移动项目开发笔记(管理不同解决方案下的DLL文件相互引用之心得体会)

    当项目比较庞大时候Dll文件的管理显得就尤其重要了,比如多个解决方案有不同项目之间的引用,如果引用的路径都指向某项目bin下的dll文件的话,dll维护起来很不方面,因此遇到这种情况的话该怎么更好的管 ...

  7. Spring-属性文件自身的引用03

    导读 用法 导读 Spring-使用外部属性文件01 Spring-使用加密的属性文件02 Spring-属性文件自身的引用03 用法 Spring既允许在Bean定义中通过${propName}引用 ...

  8. Python模块之间的相互引用问题

    在某次运行过程中出现了如下两个报错: 报错1: ModuleNotFoundError: No module named '__main__.src_test1'; '__main__' is not ...

  9. 终于搞懂了Python模块之间的相互引用问题

    摘要:详细讲解了相对路径和绝对路径的引用方法. 在某次运行过程中出现了如下两个报错: 报错1: ModuleNotFoundError: No module named '__main__.src_t ...

最新文章

  1. Java 的序列化和反序列化,你该知道得更多
  2. 并发编程(一)__volatile关键字
  3. Windows Terminal完整指南
  4. mysql三高讲解(二):2.2 B+树的B的意义
  5. python3正则表达式判断ipv4_Python 正则表达式验证IPv4地址
  6. 【Hadoop】HDFS三组件:NameNode、SecondaryNameNode和DataNode
  7. 腾讯X5webview集成
  8. 基于java+SpringBoot+HTML+Mysql)疫情防控微信小程序
  9. Mysql安装步骤:
  10. Win7定时任务——提醒自己喝水
  11. java兔子繁殖总数_Java 兔子繁殖迭代问题
  12. 原版XP合集,非BT下载
  13. 红帽linux安装打印机教程,RHEL5下安装纯文本打印机试验步骤记
  14. 都是S赛,为什么EDG夺冠公认“含金量最高”?
  15. 打开exchange2007管理控制台时,提示没有读取服务器安全描述符的权限
  16. 准确率99.9%!小猿口算靠AI批改数学题,误判率仅为人工1/10,计算填空应用题都能批改...
  17. 为什么springcloud值得我们学习?
  18. c语言内存越界例子,内存越界的可能情况分析,C语言内存越界详解
  19. 华中师范大学CCNU校园网(有线/无线)自动登录程序
  20. 妙控2代鼠标用于Windows系统注册表修改方法

热门文章

  1. ubuntu18安装vnpyv1.9.2之二
  2. 让领导狂夸,让业务目瞪口呆的报表,竟然是这样?
  3. Flex控制对主机网页中脚本的访问
  4. list(链表)容器
  5. 华北水利水电大学计算机研究生调剂,2017年华北水利水电大学考研调剂公告
  6. android 对java 支持_Android在未来对 Java 8 特性的支持
  7. 分子排列不同会导致_东华大学《高分子物理》各章选择判断题
  8. c语言中通过键盘给一维数组赋值怎么_编程C语言进阶篇——构造类型:数组
  9. opencv裁剪图片_前端智能化实践——从图片识别UI样式
  10. 一个软件公司需要多少前端_内幕!软件外包公司开发一个软件需要多少钱?