从非WPF代码访问WPF XAML资源

时间:2009-03-03 21:59:33

标签: c# wpf embedded-resource

我目前正在构建一个由多个组件组成的应用程序,每个组件本质上都是一个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;
    }
}

我找不到从“普通”C#类读取该资源(这是一个.xaml文件,并在自定义控件的ResourceDictionary中引用)的方法。任何属于WPF的东西都有那个不错的TryFindResource方法但是怎么办呢?我不希望XAML文件的图标位于未嵌入的位置。

4 个答案:

答案 0 :(得分:2)

在您的XAML代码中,确保图标资源的构建选项设置为“Resource”,然后引用该资源以使其成为xaml静态资源

<UserControl.Resources>
    <BitmapImage x:Key="icon1" UriSource="Resources/Icon1.ico" />
</UserControl.Resources>

然后在.Net 2.0代码中,您将在“{xamlName} .g.resource”流中找到该资源

将xaml dll中的所有图标加载到字典中的示例代码:

using System.IO;
using System.Reflection;
using System.Collections;
using System.Resources;

...

var icons = new Dictionary<String, Bitmap>();
var externalBaml = Assembly.LoadFile(Path.Combine(Environment.CurrentDirectory, "MyXaml.dll"));
Stream resourceStream = externalBaml.GetManifestResourceStream(externalBaml.GetName().Name + ".g.resources");
using (ResourceReader resourceReader = new ResourceReader(resourceStream)) {
    foreach (DictionaryEntry resourceEntry in resourceReader) {
        if (resourceEntry.Key.ToString().ToUpper().EndsWith(".ICO")) {
            icons.Add(resourceEntry.Key.ToString(), Image.FromStream(resourceEntry.Value as Stream) as Bitmap);
        }
    }
}

答案 1 :(得分:1)

我的建议是:

  • 提供有关您可以找到图标位置的控件的元数据。您可以使用自己的自定义属性执行此操作(请参阅下面的示例1)。此元数据将允许您加载图标而不创建控件实例。

  • 由于您使用的是MEF,因此您可以在导出中使用元数据,以实现与上述相同的功能。详情here。见下面的例子。

  • 将您的图标视为ImageSource而不是Brush。您可以使用WPF的Image控件来显示ImageSource,也可以使用ImageBrush进行绘制。

  • 使用TFD提供的技术读取具有元数据中指定名称的资源。不幸的是,WPF似乎没有提供像BamlReader这样的东西,这使得从非WPF上下文加载WPF资源变得更加清晰。

示例1:

[Icon("MyIconResourceName")]
public class BlahControl : Control
{
    ...
}

示例2:

[Export(typeof(IApplicationComponent))]
[ExportMetadata("IconResource", "MyIconResourceName")]
public class BlahControl : Control
{
    ...
}

答案 2 :(得分:0)

您可以从程序集中读取资源。

此处的示例代码: http://www.wpftutorial.net/ReadWPFResourcesFromWinForms.html

答案 3 :(得分:0)

在app.xaml或主资源字典xaml文件中,在app级别而不是在控件中定义图标。然后,您可以使用相同的TryFindResource方法,但不创建控件的实例。

相关问题