2010-01-11 2 views
111

Есть ли способ перебрать все ресурсы в файле .resx на C#?Прокрутите все ресурсы в файле .resx

+1

Вы можете уточнить, является ли внутренним для вашего проекта или вы хотите ли файл Resx (или нужно) прочитать отдельный файл RESX или прочитать RESX с другой сборки? – Abel

ответ

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

+6

@JoeFletch: ему не нужна эта строка. Код вызывает файл ресурсов напрямую. Пример: у меня есть файл с именем PageList.resx, затем я вызову: ResourceSet resourceSet = PageList.ResourceManager.GetResourceSet (CultureInfo.CurrentUICulture, true, true); – Gabriel

+0

@Gabriel, спасибо за обновление! Мне нужно вернуться к моему коду, чтобы проверить это. – JoeFletch

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

Blogged об этом 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

Можете ли вы перечислить ресурсы * не *, расположенные в папке «Ресурс»? Я хотел бы перечислить все изображения ресурсов, расположенные в моем проекте, в папке «Изображения». –

+0

Довольно уверен, что ему не важно, где он находится? Попробуй это? – Svish

+1

У меня были файлы в папке для inporting sql-файлов, и это сработало отлично. Я добавил преобразование из потока в строку, чтобы я мог прочитать файл и не имел никаких проблем. – ErocM

5

В тот момент, когда вы добавляете в проект проект ресурса .RESX, Visual Studio создаст конструктор с таким же именем, создав для вас класс aa со всеми элементами ресурса как статические свойства , Вы можете увидеть все имена ресурса при вводе точки в редакторе после ввода имени файла ресурса.

В качестве альтернативы вы можете использовать отражение для прокрутки этих имен.

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

Зачем использовать отражение при наличии ресурса? –

+0

Вот что мне было бы интересно (см. Последний абзац). Просто хотел показать альтернативный метод, но что более важно, хотел показать, что класс полностью доступен, и вам не нужно делать какую-либо магию вручную (первый абзац). – Abel

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 –

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); 
} 
Смежные вопросы