再吐槽一下(我已经无力吐槽)。今天又被资源搞了一天,发现了一个秘密。大家想听就跟随我...
以前写的一个东东,想用mvvm重新实现一下,由于之前的写得很乱,App.xaml里一坨一坨的,就把资源整到一个单独的资源文件里,然后到App.xaml去Merged,这思路是对的。然而当我整完之后,程序运行起来了,没问题,但是在VS2010编辑器里打开每个窗体或者用户控件的时候,就出错了,错误如下:
错误 1 “{DependencyProperty.UnsetValue}”不是 Setter 上“System.Windows.Controls.Border.BorderBrush”属性的有效值。
这个错不是什么大问题,不就是一个资源没有找到么,给它找到,或者不要这个资源,我估计就没问题了。于是想去找出错的资源,发现居然没有地方有明显的错误。一般双击错误里的行会自动导航到出错的地方,然而当我双击错误时,VS并没有给我导航到那里,这可有点难为我了,上万行的资源,叫我怎么去定位呢?各位大牛,如果是你遇到这情况,你会如何处理?
首先,我得确定到底是不是资源的问题,把App.xaml里Merged的东东全部注掉,不用资源,顶多运行时报个找不到资源的错误,界面还是起得来的。注掉后重新编译,果然界面是起来了,就是丑点,这是我希望看到的结果,现在可以确定,是资源引起的。
然后,我看他的错误,BorderBrush的值无效,Ctrl+F在资源文件里找到所有的属性名为BorderBrush的属性,看他引用的值,然后挨个找,结果大失所望,引用的资源全部能找到。
接着,我跟没改动之前的项目结构对比了一下,发现资源文件里需要引用到一些图片,之前资源文件和图片文件是在同一个目录下的,整合之后,图片文件在一个文件夹里,资源文件也在单独的文件夹里,我考虑,是不是没有找到图片资源呢(其实上面的步骤做下来脑子有点昏了),网上搜了下,Image的Source属性不管是设根目录,相对路径、绝对路径还是程序集路径,都解决不了这个问题,索性把这些图片引用统统去掉,到最后每次打开界面居然不报错了,界面依然加载不起来。而且我发现,在这个项目下面就算是新创建一个窗口或者用户控件,界面依然起不来,按常理新建的窗体赤裸裸的并不引用任何资源,应该是能起来的,有点虚了...
在这个解决方案下新建一个工程,再新建窗体,可以起来,起不来才怪呢,我怀疑是项目名称取得不好导致的,这想法我后来想想挺好笑的。
其实这时候已经没辙了,我可不想一个个重新去弄样式,那么多再来一遍不是几个小时能解决的。再想想,之前的项目怎么是好好的,现在怎么不好了,我只不过把App.xaml里面的东东挪了下位置而已,为何会有此结果?好吧,既然你有好用的,用对比工具对比一下,看看究竟哪里差了,不就行了,说干就干,BeyondCompare开起来,对比后的结果让我目瞪口呆。两个文件,除去没有关系的差异,真正影响到这个问题的差异就只有两行!哪两行呢,某个Style用到BorderBrush,好用的那个放在了上面,不好用的那个放在了这个Style的下面,位置一调,就正常了,我去啊。
xaml作为智能标记语言,没想到也这么蠢,吐槽一下,纯属牢骚,解释语言嘛,想想也不要要求太高,不过这个错真实错得无厘头。
总结:WPF涉及到资源的嵌套引用,被引用的资源要定义在引用的资源前面,否则,也没关系,只是编辑器里看不到漂亮的界面而已。