7

我目前正在构建一个由多个组件组成的应用程序,每个组件本质上都是一个 WPF 用户控件,周围有一些 C# 代码,以便插件系统工作(使用 MEF)。

我遇到的问题是每个组件都应该包含一个图标,出于美观的目的,我将其定义为一个System.Windows.Media.Brush,所以我可以在DrawingBrush那里使用从 Design 导出的内容。现在我需要从非 WPF C# 访问那段 XAML,我目前有一个可怕的解决方法是实例化用户控件并询问它的资源:

private Brush CachedIcon = null;

public override Brush Icon
{
    get
    {
        if (CachedIcon == null)
        {
            CachedIcon = (Brush)(new BlahControl().TryFindResource("Icon"));
        }
        return CachedIcon;
    }
}

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

4

4 回答 4

2

在您的 XAML 代码中,确保图标资源的构建选项设置为“资源”,然后引用该资源以使其成为 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);
        }
    }
}
于 2009-03-09T23:52:49.860 回答
1

我的建议是:

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

  • 由于您使用的是 MEF,因此您可以在导出中使用元数据来实现与上述相同的效果。详情在这里。请参见下面的示例 2。

  • 将您的图标视为一个ImageSource而不是一个Brush. 您可以使用 WPF 的Image控件来显示您的ImageSource,也可以使用ImageBrush.

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

示例 1:

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

示例 2:

[Export(typeof(IApplicationComponent))]
[ExportMetadata("IconResource", "MyIconResourceName")]
public class BlahControl : Control
{
    ...
}
于 2009-03-12T09:24:58.720 回答
0

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

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

于 2009-03-03T22:04:26.083 回答
0

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

于 2009-03-08T17:19:33.153 回答