поиск и перечисление словарей ресурсов WPF в папке

StackOverflow https://stackoverflow.com/questions/1765920

Вопрос

Я создаю приложение WPF, которое будет иметь несколько скинов, фирменных для нашей системы сборки.В идеале мы хотели бы, чтобы в приложении был список доступных скинов, поскольку в некоторых сборках будет от одного до нескольких скинов.

Есть ли способ во время выполнения перечислить все словари ресурсов в определенной папке?

Я хочу избежать жесткого кодирования имен файлов XAML в моем codebehind, поскольку это меняющаяся ситуация.

Это было полезно?

Решение

Вроде того.

Вы можете перечислить все файлы 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 или UserControls, без их фактической загрузки.Таким образом, ответ на ваш прямой вопрос будет "нет", если вы не загрузите каждый найденный XAML, чтобы проверить, является ли это ResourceDictionary.Это было бы очень медленно.

С другой стороны, если вы готовы использовать схему именования для своих ResourceDictionaries, то вы можете перечислить все BAMLS в своей сборке и выбрать тот, который соответствует вашей схеме именования, и быть уверенным, что это ResourceDictionaries.Просто расширьте предложение "where" в приведенном выше запросе.

Поэтому ответ будет "вроде того".

Другие советы

вот решение, которое я нашел @ microsoft

WPF обертывает ResourceDictionary в "Assembly.g.resources" мы можем получить имя ресурса "Assembly.g.resources" с помощью GetManifestResourceNames().После этого мы можем использовать 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)
   {
    .....
   }
  }
 }
}

Вы можете добавить ResourceDictionary во время выполнения.

Resources.MergedDictionaries.Add(...)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top