【问题标题】:searching and listing WPF resource dictionaries in a folder在文件夹中搜索和列出 WPF 资源字典
【发布时间】:2010-12-18 11:10:00
【问题描述】:

我正在制作一个 WPF 应用程序,该应用程序将有多个由我们的构建系统标记的皮肤。理想情况下,我们希望应用程序列出可用的皮肤,因为某些构建将具有一对多皮肤。

在运行时有没有办法枚举特定文件夹中的所有资源字典?

我想避免在我的代码隐藏中对 XAML 文件名进行硬编码,因为这是一种不断变化的情况。

【问题讨论】:

    标签: wpf search list resourcedictionary


    【解决方案1】:

    这是我在@microsoft 找到的解决方案

    WPF 将ResourceDictionary 包装在“Assembly.g.resources”中,我们可以通过GetManifestResourceNames() 获取资源名称“Assembly.g.resources”。之后我们可以使用ResourceReader类从ResourceStream读取资源。

     foreach (string str in Application.ResourceAssembly.GetManifestResourceNames()){
    txt.Text += str + "\n";
     {
      Stream st = Application.ResourceAssembly.GetManifestResourceStream(str);
      using (ResourceReader resourceReader = new ResourceReader(st))
      {
       foreach (DictionaryEntry resourceEntry in resourceReader)
       {
        txt.Text +="\t: "+ resourceEntry.Key + "\n";
       }
      }
     }
    }
    

    第二个答案

    您可以使用Assembly.Load() 加载外部程序集并从中读取资源字典。

    Assembly assembly = Assembly.Load("Assembly Name String"); 
    foreach (string str in assembly.GetManifestResourceNames())
    {
     {
      Stream st = assembly.GetManifestResourceStream(str);
      using (ResourceReader resourceReader = new ResourceReader(st))
      {
       foreach (DictionaryEntry resourceEntry in resourceReader)
       {
        .....
       }
      }
     }
    }
    

    【讨论】:

      【解决方案2】:

      有点。

      您可以按如下方式枚举所有 BAML(已编译的 XAML)文件:

        var resourcesName = assembly.GetName().Name + ".g";
        var manager = new System.Resources.ResourceManager(resourcesName, assembly);
        var resourceSet = manager.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
        var allXamlFiles =
          from entry in resourceSet.OfType<DictionaryEntry>()
          let fileName = (string)entry.Key
          where fileName.EndsWith(".baml")
          select fileName.Substring(0, fileName.Length-5) + ".xaml";
      

      如果不实际加载它们,就无法知道其中哪些是 ResourceDictionaries,哪些是其他 XAML,例如 Windows 或 UserControl。因此,除非您加载找到的每个 XAML 以检查它是否是 ResourceDictionary,否则您直接问题的答案是“否”。这会很慢。

      另一方面,如果您愿意为 ResourceDictionaries 使用命名方案,则可以枚举程序集中的所有 BAML 并选择与您的命名方案匹配的任何一个,并相信它们是 ResourceDictionaries。只需扩展上述查询中的“where”子句即可。

      因此答案是“有点”。

      【讨论】:

      • 我能理解你所理解的概念,但它不适合我。我假设“程序集”来自 Assemgly.GetExecutingAssembly()。管理器的构造函数也可能是 ResourceManager(resourcesName, assembly)。但是我认为 LINQ 查询不正确,因为 resourceSet 没有 OfType() 函数
      • 我从我自己的工作应用程序代码中复制了这个,但是当我粘贴代码时,我做了一些最后的重构并弄乱了 ResourceManager 构造函数。我已经修复了我的答案以纠正错误。
      • 至于另一个错误,我想你只是忘了using System.Linq;,因为那里声明了OfType&lt;&gt;()扩展方法。
      【解决方案3】:

      您可以在运行时添加 ResourceDictionary。

      Resources.MergedDictionaries.Add(...)
      

      【讨论】:

      • 我不知道皮肤的名称,所以我需要在添加它们之前先列出它们。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多