Jane的问题实际上与这个有关,我也遇到了同样的问题。我已经按照Foovanadil的建议创建了ResourceDictionary的子类,但是在设计时会抛出“Uri前缀未被识别”的异常。
即使所有子类所做的只是分配ResourceDictionary的base.Source属性,我仍然会收到此错误。如果我用常规的ResourceDictionary替换我的自定义ResourceDictionary,它就可以正常工作,因此我猜测cider设计师做了一些特殊的事情,可能是用其他东西替换了ResourceDictionary。
我还没有在Blend中尝试过这个,但我在VS2010(sp1 beta)中确实遇到了这个问题。有人能确认发布的答案在vs2010中是否有效吗?
-编辑-
有可能是基于wpf的设计师在资源定位逻辑方面出了问题。我在其他地方读到,pack uri是基于“执行”程序集而不是“本地”程序集的。我会报告我找到的内容
-编辑2/解决方案-
好的,我成功地在VS2010中使用了Foovanadil解决方案,这是个交易。结果证明我是对的一半,可能是因为VS2010中的wpf设计师本身就是用wpf编写的,或者为了提供更好的设计体验,ResourceDictionary(或者VS2010使用的其他类)在设计时表现不同。
事实证明,VS替换了在xaml中输入的URI。连接到VS实例并在Source
的setter中设置断点会发现实际传递的值与我们期望的值不同。
给定xaml:
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<local:DesignTimeResourceDictionary Source="myxamlfile.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
Source
已设置为
markup://1/file:///c:/PathtoMyapp/MainWindow.xaml#0/myxamlfile.xaml
而不是
/myxamlfile.xaml
这就是为什么我们会得到无效URI异常的原因。
关于VS2010在设计时如何编辑URI以及何时编辑,我并不清楚,但是将DesignTimeResourceDictionary
中的Source
属性重命名为其他名称并不能解决问题。
幸运的是,有一个解决方法。如果我们将Source
的类型从Uri
更改为String
,则VS设计器不会修改该值。在setter中,我们创建一个Uri并将其传递给基本属性:
public new String Source {
get {
return base.Source.ToString();
}
set {
if( !IsInDesignMode )
return;
base.Source = new Uri( value, UriKind.RelativeOrAbsolute );
}
}
请注意,如果您使用此方法(或任何其他我发现的方法,例如在资源文件中使用x:class并直接从xaml实例化),
将导致样式在构建之前不会更新。使用标准的ResourceDictionary将导致设计师在编辑导入的资源文件后立即更新(甚至在保存之前)。这也表明设计师在设计时以不同的方式处理ResrouceDictionary。
希望有人会发现这个有用 :)
ResourceDictionary
在同一个项目中,这种方法非常有用。然而,在Blend 4中,我无法让它在ResourceDictionary
位于不同项目的情况下工作。对于这些情况,我不得不采用这种方法。 - Jason Frank