【问题标题】:How to get a list of XAML resources defined in an Assembly?如何获取程序集中定义的 XAML 资源列表?
【发布时间】:2016-04-15 06:25:53
【问题描述】:

是否可以枚举程序集中定义的所有 XAML 资源?如果您有可用的密钥,我知道如何检索资源,但在我的情况下并非如此。

编辑: 好像我说的不够清楚。我想列出在我知道完整路径的 external 程序集中定义的 XAML 资源。

【问题讨论】:

  • 你想要所有的资源,不管它们是否定义在 app/window/usercontrol/style 中?
  • 我只需要外部可用资源。我认为您不能使用在另一个程序集的 UserControl/Window 中定义的资源,对吧?

标签: c# wpf xaml


【解决方案1】:

是的,您可以通过循环迭代资源。比如使用foreach循环:

foreach (var res in Application.Current.Resources)
{
     Console.WriteLine(res);
}

更新:

要从外部库中获取所有ResourceDictionary'ies,您应该首先加载库,然后获取ManifestResourceInfo。让我举个例子:

string address = @"WpfCustomControlLibrary.dll";
List<Stream> bamlStreams = new List<Stream>();
Assembly skinAssembly = Assembly.LoadFrom(address);            
string[] resourceDictionaries = skinAssembly.GetManifestResourceNames();
foreach (string resourceName in resourceDictionaries)
{
   ManifestResourceInfo info = skinAssembly.GetManifestResourceInfo(resourceName);
   if (info.ResourceLocation != ResourceLocation.ContainedInAnotherAssembly)
   {
      Stream resourceStream = skinAssembly.GetManifestResourceStream(resourceName);
      using (ResourceReader reader = new ResourceReader(resourceStream))
      {
         foreach (DictionaryEntry entry in reader)
         {
            //Here you can see all your ResourceDictionaries
            //entry is your ResourceDictionary from assembly
          }
      }
    }
}

您可以在reader 中查看您所有的ResourceDictionary。请看上面的代码。

我已经测试了这段代码,它可以工作。

【讨论】:

  • 抱歉,我的问题好像不太清楚。我想列出当前未加载到 AppDomain 中的外部程序集的资源。
  • 很遗憾,我认为它不会列出 XAML 中定义的资源。
  • @ionoy 请看我更新的答案。我已经测试了这段代码,它可以工作。
【解决方案2】:

试试下面的代码:

        ResourceDictionary dictionary = new ResourceDictionary();
        dictionary.Source = new Uri("pack://application:,,,/WpfControlAssembly;Component/RD1.xaml", UriKind.Absolute);
        foreach (var item in dictionary.Values)
        {
           //Operations
        }

这里WpfControlAssembly 是您的程序集的名称。Component 是固定值,然后RD1.xamlResource Dictionary

下面是输出:

资源字典

代码输出:

PS:所有ResourceDictionary 文件都应该有Build Action'Resource''Page'

更新:

我终于可以做到了。请使用以下方法:

public ResourceDictionary GetResourceDictionary(string assemblyName)
    {
        Assembly asm = Assembly.LoadFrom(assemblyName);
        Stream stream = asm.GetManifestResourceStream(asm.GetName().Name + ".g.resources");            
        using (ResourceReader reader = new ResourceReader(stream))
        {
            foreach (DictionaryEntry entry in reader)
            {
                var readStream = entry.Value as Stream;
                Baml2006Reader bamlReader = new Baml2006Reader(readStream);
                var loadedObject = System.Windows.Markup.XamlReader.Load(bamlReader);
                if (loadedObject is ResourceDictionary)
                {
                    return loadedObject as ResourceDictionary;
                }
            }
        }
        return null;
    }

输出:

没有任何 try-catch 和预期的 Exceptions,我认为更多的是 WPF(而不是将所有内容都转换为 ResourceDictionary)方式。

【讨论】:

  • 但是如果我不知道 ResourceDictionary (RD1.xaml) 的名称怎么办?是否可以在程序集中找到所有 ResourceDictionaries 的名称?
  • 如果您不知道 ResourceDictionaries 的名称,您可以从 AssamblyInfo 获取,但如果您不知道名称,您将如何在其中找到资源。我的意思是,如果您不知道 .ResourceDictionaries 的名称,但知道其中的资源名称,这对我来说似乎很讽刺。我不确定你想在这里实现什么。
  • @ionoy 你对这个程序集有哪些详细信息?
  • 基本上只是完整路径而已。既然我只想列举资源,那应该就够了。我认为@StepUp 已经提出了一个足够好的解决方案。还是给你 +1,谢谢!
  • 同意。如果它在 XAML 平台之间保持一致,那么它是一种性能更高的方法。
猜你喜欢
  • 2019-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多