循环遍历.resx文件中的所有资源


124

有没有办法遍历.resxC#文件中的所有资源?


2
您能否详细说明RESX文件是否在项目内部,还是要(或需要)读取一个单独的RESX文件或从另一个程序集中读取RESX?
亚伯2010年

Answers:


242

您应该始终使用资源管理器,而不是直接读取文件,以确保考虑到全球化。

using System.Collections;
using System.Globalization;
using System.Resources;

...

/* Reference to your resources class -- may be named differently in your case */
ResourceManager MyResourceClass =
    new ResourceManager(typeof(Resources));

ResourceSet resourceSet =
    MyResourceClass.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
foreach (DictionaryEntry entry in resourceSet)
{
    string resourceKey = entry.Key.ToString();
    object resource = entry.Value;
}

12
我花了一点时间才弄清楚您需要此行来声明MyResourceClass。ResourceManager MyResourceClass = new ResourceManager("Resources.ResourceFileName", System.Reflection.Assembly.Load("App_GlobalResources"));
JoeFletch 2012年

6
@JoeFletch:它不需要这一行。该代码直接调用资源文件。示例:我有一个名为PageList.resx的文件,然后我将调用:ResourceSet resourceSet = PageList.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture,true,true);
加百利

@Gabriel,感谢您的更新!我将不得不回到我的代码以进行检查。
JoeFletch

3
JoeFletch的电话线实际上帮助了我。我在另一个C#项目中有一个resx,因此他的代码行使我可以调用dll程序集并以这种方式加载资源。另外,当我尝试在代码中包括PageList时,它为PageList.ResourceManager ..抛出了一个错误,说“ PageList不包含ResourceManager的定义”。最后,字符串resourceKey = entry.Key引发了错误,我改用“ object resourceKey = entry.Key”
sksallaj 2013年

2
根据您是否确实在资源中定义了区域性,您将不得不切换到CultureInfo.InvariantCulture。在这里,我使用的是库中的资源,而不是WinForms应用程序。
以色列洛佩兹

26

博客上讲述它在我的博客 :)短的版本是,寻找资源的全名(除非你已经知道它们):

var assembly = Assembly.GetExecutingAssembly();

foreach (var resourceName in assembly.GetManifestResourceNames())
    System.Console.WriteLine(resourceName);

要将它们全部用于某事:

foreach (var resourceName in assembly.GetManifestResourceNames())
{
    using(var stream = assembly.GetManifestResourceStream(resourceName))
    {
        // Do something with stream
    }
}

要在执行程序集之外的其他程序集中使用资源,您可以通过使用Assembly该类的其他一些静态方法来获得不同的程序集对象。希望能帮助到你 :)


您可以枚举不在 “资源”文件夹中的资源吗?我想枚举项目中位于“ Images”文件夹中的所有资源图像。
西蒙·博斯利

可以确定它不在乎它的位置吗?测试吗?
Svish

1
我在用于导入sql文件的文件夹中有文件,并且此方法运行良好。我添加了从流到字符串的转换,因此我可以读取文件,没有任何问题。
ErocM

9

使用ResXResourceReader类

ResXResourceReader rsxr = new ResXResourceReader("your resource file path");

// Iterate through the resources and display the contents to the console.
foreach (DictionaryEntry d in rsxr)
{
    Console.WriteLine(d.Key.ToString() + ":\t" + d.Value.ToString());
}

7
  // Create a ResXResourceReader for the file items.resx.
  ResXResourceReader rsxr = new ResXResourceReader("items.resx");

  // Create an IDictionaryEnumerator to iterate through the resources.
  IDictionaryEnumerator id = rsxr.GetEnumerator();       

  // Iterate through the resources and display the contents to the console.
  foreach (DictionaryEntry d in rsxr) 
  {
Console.WriteLine(d.Key.ToString() + ":\t" + d.Value.ToString());
  }

 //Close the reader.
 rsxr.Close();

请参阅链接:Microsoft示例


4
请注意,此类是在System.Windows.Forms程序集中的,如果您使用的是MVC应用,则不会自动添加
Rob Scott

6

将资源.RESX文件添加到项目中的那一刻,Visual Studio将创建一个具有相同名称的Designer.cs,为您创建一个类,将资源的所有项目作为静态属性。在键入资源文件的名称后,在编辑器中键入点时,可以看到资源的所有名称。

另外,您可以使用反射来遍历这些名称。

Type resourceType = Type.GetType("AssemblyName.Resource1");
PropertyInfo[] resourceProps = resourceType.GetProperties(
    BindingFlags.NonPublic | 
    BindingFlags.Static | 
    BindingFlags.GetProperty);

foreach (PropertyInfo info in resourceProps)
{
    string name = info.Name;
    object value = info.GetValue(null, null);  // object can be an image, a string whatever
    // do something with name and value
}

该方法显然仅在RESX文件在当前程序集或项目的范围内时才可用。否则,请使用“脉冲”提供的方法。

此方法的优点是,您可以调用已提供给您的实际属性,并且可以根据需要考虑任何本地化。但是,这是多余的,因为通常应使用类型安全直接方法来调用资源的属性。


2
当有ResourceSet可用时,为什么要使用反射?
Oundless 2010年

这也是我想知道的(请参阅上一段)。只是想展示一种替代方法,但更重要的是,想展示该类具有完全可访问性,并且您无需手工做任何魔术(第一段)。
亚伯2010年


1

如果要使用LINQ,请使用resourceSet.OfType<DictionaryEntry>()。例如,使用LINQ可让您根据索引(int)而不是键(string)来选择资源:

ResourceSet resourceSet = Resources.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
foreach (var entry in resourceSet.OfType<DictionaryEntry>().Select((item, i) => new { Index = i, Key = item.Key, Value = item.Value }))
{
    Console.WriteLine(@"[{0}] {1}", entry.Index, entry.Key);
}

1

对于nuget软件包System.Resources.ResourceManager(v4.3.0),ResourceSetResourceManager.GetResourceSet均不可用。

使用ResourceReader,如本文所建议:“ C#-无法从ResourceManager(从附属程序集)获取字符串

仍然可以读取资源文件的键/值。

System.Reflection.Assembly resourceAssembly = System.Reflection.Assembly.Load(new System.Reflection.AssemblyName("YourAssemblyName"));
String[] manifests = resourceAssembly.GetManifestResourceNames(); 
using (ResourceReader reader = new ResourceReader(resourceAssembly.GetManifestResourceStream(manifests[0])))
{
   System.Collections.IDictionaryEnumerator dict = reader.GetEnumerator();
   while (dict.MoveNext())
   {
      String key = dict.Key as String;
      String value = dict.Value as String;
   }
}

0

使用LINQ to SQL

XDocument
        .Load(resxFileName)
        .Descendants()
        .Where(_ => _.Name == "data")
        .Select(_ => $"{ _.Attributes().First(a => a.Name == "name").Value} - {_.Value}");

0

简单的读取循环使用此代码

var resx = ResourcesName.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, false, false);

foreach (DictionaryEntry dictionaryEntry in resx)
{
    Console.WriteLine("Key: " + dictionaryEntry.Key);
    Console.WriteLine("Val: " + dictionaryEntry.Value);
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.