searching and listing WPF resource dictionaries in a folder

前端 未结 3 700
失恋的感觉
失恋的感觉 2021-01-19 07:10

I\'m making a WPF application that is going to have multiple skins branded in by our build system. Ideally we would like the application to list off the skins available as

相关标签:
3条回答
  • 2021-01-19 07:34

    Sort of.

    You can enumerate all BAML (compiled XAML) files as follows:

      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";
    

    There is no way to know which ones of these are ResourceDictionaries and which are other XAML such as Windows or UserControls without actually loading them. So the answer to your direct question is "no" unless you load each XAML you find to check if it is a ResourceDictionary. This would be very slow.

    On the other hand, if you're willing to use a naming scheme for your ResourceDictionaries, then you can enumerate all BAMLs in your assembly and select whichever match your naming scheme, and trust that they are ResourceDictionaries. Just extend the "where" clause in the above query.

    Therefore the answer is "sort of."

    0 讨论(0)
  • 2021-01-19 07:35

    here is a solution i found @ microsoft

    WPF wraps the ResourceDictionary in the "Assembly.g.resources", we can get the resource name "Assembly.g.resources" by GetManifestResourceNames(). After that we can use ResourceReader class to read the Resource from the 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";
       }
      }
     }
    }
    

    second answer

    You can use Assembly.Load() to load the external assembly and read the resource dictionaries from it.

    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)
       {
        .....
       }
      }
     }
    }
    
    0 讨论(0)
  • 2021-01-19 07:41

    You can add ResourceDictionary at runtime.

    Resources.MergedDictionaries.Add(...)
    
    0 讨论(0)
提交回复
热议问题