2010-01-11 153 views
111

有没有办法循环遍历C#中.resx文件中的所有资源?循环遍历.resx文件中的所有资源

+1

你能在RESX文件是否是内部项目还是你想阐述​​(或需要)读取一个单独的RESX文件或从另一个程序集读取RESX? – Abel 2010-01-11 10:18:09

回答

211

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

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

... 


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

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-09-20 02:11:17

+6

@JoeFletch:它不需要这一行。代码直接调用资源文件。例如:我有一个名为PageList.resx的文件,然后我会调用:ResourceSet resourceSet = PageList.ResourceManager.GetResourceSet(CultureInfo。CurrentUICulture,真实,真实); – Gabriel 2013-02-06 11:23:57

+0

@Gabriel,感谢您的更新!我将不得不回到我的代码来检查这一点。 – JoeFletch 2013-02-06 13:25:07

7

使用ResXResourceReader Class

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()); 
} 
23

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

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类的其他静态方法获得不同的程序集对象。希望它有所帮助:)

+0

您可以枚举名为'资源'的文件夹中的资源*而非*吗?我想枚举位于我的项目中的所有资源图像在名为'图像'的文件夹中。 – 2016-04-27 08:23:15

+0

很确定它不关心它的位置?测试它? – Svish 2016-04-30 20:07:28

+1

我有一个用于导入sql文件的文件夹,并且这个工作完美。我添加了从流到字符串的转换,所以我可以读取该文件并且没有问题。 – ErocM 2016-08-23 18:16:25

5

将资源.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可用时使用反射? – 2010-01-11 10:12:18

+0

这就是我想知道的(见最后一段)。只是想展示一种替代方法,但更重要的是,想要表明该课程是完全可以访问的,并且不需要手工操作(第一段)。 – Abel 2010-01-11 10:14:02

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 example

+3

请注意,这个类位于'System.Windows.Forms'程序集中,如果您使用的是MVC应用程序,则不会自动添加 – 2016-08-22 17:18:06

0

使用LINQ to SQL

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

如果你想使用LINQ,使用resourceSet.OfType<DictionaryEntry>()。使用LINQ可以让你,例如,基于其指数(INT)选择资源,而不是重点(串):

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); 
}