2010-01-11 65 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); 
}