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.

È stato utile?

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(...)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top