我正在为WPF应用程序制作一个主题编辑器。我动态生成XAML文件,然后将它们编译成应用程序使用的DLL。用于生成XAML文件的代码如下所示:
var dictionary = new ResourceDictionary();
...
dictionary.Add(key, new BitmapImage { UriSource = new Uri(relativePath, UriKind.Relative) });
...
XamlWriter.Save(dictionary, "myDictionary.xaml");
我的问题是XamlWriter.Save
还序列化了BaseUri
属性:
<BitmapImage BaseUri="{x:Null}" UriSource="ImagesmyImage.png" x:Key="myImage" />
结果是,当应用程序尝试获取此图像时,由于未设置BaseUri
,因此找不到它。通常XAML解析器设置此属性(通过IUriContext
接口),但当它已经在XAML中显式设置时,解析器不会设置它,因此它保持为null。
是否有方法阻止XamlWriter
序列化BaseUri
属性
如果我正在序列化一个自定义类,我可以添加一个ShouldSerializeBaseUri()
方法,或者显式实现IUriContext
(我尝试了这两个选项,它们都给出了所需的结果),但如何为BitmapImage
做到这一点呢?
作为最后的手段,我可以加载XAML文件并将带有Linq-to-XML的属性删除,但我希望有一个更干净的解决方案。
如果我们不阻止XamlWriter
写入BaseUri
属性,而是给它一些不影响图像加载的东西,会怎么样?例如以下代码:
<Image>
<Image.Source>
<BitmapImage UriSource="Resources/photo.JPG"/>
</Image.Source>
</Image>
似乎相当于
<Image>
<Image.Source>
<BitmapImage BaseUri="pack://application:,," UriSource="Resources/photo.JPG"/>
</Image.Source>
</Image>
尝试
dictionary.Add("Image", new BitmapImage{
BaseUri=new Uri("pack://application:,,"),
UriSource = new Uri(@"ImagesmyImage.png", UriKind.Relative)
});
如果你试图将图像源设置为通过这种方式从代码中创建的BitmapImage,那就行不通了。但XamlWriter.Save()
生成的XAML在为XAML时确实有效:)。好吧,我希望值得一试。
我最终通过使用Linq-to-XML手动生成XAML解决了这个问题。