首页 文章

从非WPF代码访问WPF XAML资源

提问于
浏览
7

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

  • 2

    您可以从流程中读取程序集中的资源 .

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

  • 0

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

  • 1

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

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

    然后在.Net 2.0代码中,您将在“ .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);
            }
        }
    }
    
  • 0

    我的建议是:

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

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

    • 将您的图标视为 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
    {
        ...
    }
    

相关问题