我正在制作一个 WPF 应用程序,它将由我们的构建系统标记多个皮肤。理想情况下,我们希望应用程序列出可用的皮肤,因为某些构建将具有一对多的皮肤。
在运行时有没有办法枚举特定文件夹中的所有资源字典?
我想避免在我的代码隐藏中对 XAML 文件名进行硬编码,因为这是一种不断变化的情况。
我正在制作一个 WPF 应用程序,它将由我们的构建系统标记多个皮肤。理想情况下,我们希望应用程序列出可用的皮肤,因为某些构建将具有一对多的皮肤。
在运行时有没有办法枚举特定文件夹中的所有资源字典?
我想避免在我的代码隐藏中对 XAML 文件名进行硬编码,因为这是一种不断变化的情况。
有点。
您可以枚举所有 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 使用命名方案,那么您可以枚举程序集中的所有 BAML 并选择与您的命名方案匹配的任何一个,并相信它们是 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(...)