Search and enumerate WPF resource dictionaries in a folder

I am making a WPF application that will have several skins branded with our build system. Ideally, we would like the application to display a list of available skins, since some builds have one or more skins.

At runtime, is there a way to list all resource dictionaries in a specific folder?

I want to avoid hard-coding XAML file names in my code, as this is a changing situation.

+4
source share
3 answers

Sorting.

You can list all BAML files (compiled XAML) 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"; 

It is not possible to know which ones are ResourceDictionaries and which other XAMLs such as Windows or UserControls are without loading them. So the answer to your direct question is “no,” if you don't download every XAML you find to check if it is a ResourceDictionary. It will be very slow.

On the other hand, if you want to use the naming scheme for your ResourceDictionaries, you can list all the BAMLs in your assembly and choose, depending on your naming scheme, and hope that they are ResourceDictionaries. Just add the where clause in the above query.

Therefore, the answer is "kind of."

+7
source

here is the solution i found @microsoft

WPF wraps a ResourceDictionary in "Assembly.g.resources", we can get the resource name "Assembly.g.resources" on GetManifestResourceNames() . After that, we can use the 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 an external assembly and read 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) { ..... } } } } 
+2
source

You can add a ResourceDictionary at runtime.

 Resources.MergedDictionaries.Add(...) 
0
source

All Articles