cercare ed elencare i dizionari di risorse WPF in una cartella
-
21-09-2019 - |
Domanda
Sto creando un'applicazione WPF che avrà più skin marchiate dal nostro sistema di build.Idealmente vorremmo che l'applicazione elencasse le skin disponibili poiché alcune build avranno da una a molte skin.
In fase di esecuzione esiste un modo per enumerare tutti i dizionari delle risorse in una cartella specifica?
Voglio evitare di codificare in modo rigido i nomi di file XAML nel mio codebehind poiché si tratta di una situazione in evoluzione.
Soluzione
Un po '.
È possibile enumerare tutti i file BAML (XAML compilato) nel seguente modo:
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";
Non c'è modo di sapere quali di questi sono ResourceDictionaries e quali sono altri XAML come Windows o controlli utente senza peraltro riuscire a caricare. Quindi la risposta alla tua domanda diretta è "no" a meno che non si carica ogni XAML a trovare per verificare se si tratta di un ResourceDictionary. Questo sarebbe molto lenta.
D'altra parte, se siete disposti ad utilizzare uno schema di denominazione per i vostri ResourceDictionaries, allora si può enumerare tutti BAMLs nella vostra assemblea e selezionare a seconda di quale abbinare il vostro schema di denominazione, e la fiducia che essi sono ResourceDictionaries. Basta estendere il "dove" clausola nella query precedente.
Quindi la risposta è "una sorta di".
Altri suggerimenti
ecco una soluzione che ho trovato @ Microsoft
WPF avvolge il file ResourceDictionary
in "Assembly.g.resources", possiamo ottenere il nome della risorsa "Assembly.g.resources" tramite GetManifestResourceNames()
.Dopodiché possiamo usare ResourceReader
classe per leggere la risorsa da 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";
}
}
}
}
seconda risposta
Puoi usare Assembly.Load()
per caricare l'assembly esterno e leggere i dizionari risorse da esso.
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)
{
.....
}
}
}
}
È possibile aggiungere ResourceDictionary in fase di esecuzione.
Resources.MergedDictionaries.Add(...)