我目前正在构建一个由几个组件组成的应用程序,每个组件本质上都是一个WPF用户控件,周围有一些C#代码,以便插件系统工作(使用MEF) .
我遇到的问题是每个组件应该包含一个图标,为了好的目的,我将其定义为 System.Windows.Media.Brush
所以我可以使用从那里导出的 DrawingBrush
. 现在我需要从非WPF C#访问那段XAML,其中我目前有实例化用户控件并要求它获取资源的可怕解决方法:
private Brush CachedIcon = null;
public override Brush Icon
{
get
{
if (CachedIcon == null)
{
CachedIcon = (Brush)(new BlahControl().TryFindResource("Icon"));
}
return CachedIcon;
}
}
我找不到从"normal" C#类读取该资源(这是一个.xaml文件,并在自定义控件中的 ResourceDictionary
中引用)的方法 . 任何属于WPF的东西都有那么好的 TryFindResource
方法但是怎么办呢?我不希望XAML文件的图标位于未嵌入的位置 .
4 回答
您可以从流程中读取程序集中的资源 .
示例代码:http://www.wpftutorial.net/ReadWPFResourcesFromWinForms.html
在app.xaml或主资源字典xaml文件中,在应用程序级别而不是在控件中定义图标 . 然后,您可以使用相同的TryFindResource方法,但不创建控件的实例 .
在您的XAML代码中,确保图标资源的构建选项设置为“Resource”,然后引用该资源以使其成为xaml静态资源
然后在.Net 2.0代码中,您将在“ .g.resource”流中找到该资源
将xaml dll中的所有图标加载到字典中的示例代码:
我的建议是:
在您的控件上提供有关可以找到图标的位置的元数据 . 您可以使用自己的自定义属性执行此操作(请参阅下面的示例1) . 此元数据将允许您加载图标而不创建控件的实例 .
由于您正在使用MEF,因此您可以在导出中使用元数据来实现与上述相同的功能 . 详情here . 见下面的例子2 .
将您的图标视为
ImageSource
而不是Brush
. 您可以使用WPF的Image
控件来显示ImageSource
,或者您可以使用ImageBrush
绘制它 .使用TFD提供的技术读取具有元数据中指定名称的资源 . 不幸的是,WPF似乎没有提供像
BamlReader
这样的东西,这使得从非WPF上下文加载WPF资源变得更加清晰 .例1:
例2: