2010-01-11 23 views
111

¿Hay alguna forma de recorrer todos los recursos en un archivo .resx en C#?Pasa por todos los recursos en un archivo .resx

+1

Nos puedes contar acerca de si el archivo RESX es interna a su proyecto o si desea (o necesita) leer un archivo RESX por separado o leer RESX desde otro ensamblado? – Abel

Respuesta

211

Siempre debe usar el administrador de recursos y no leer archivos directamente para garantizar que se tenga en cuenta la globalización.

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

Me llevó un poco descubrir que necesita esta línea para declarar MyResourceClass. 'ResourceManager MyResourceClass = new ResourceManager (" Resources.ResourceFileName ", System.Reflection.Assembly.Load (" App_GlobalResources "));' – JoeFletch

+6

@JoeFletch: no necesita esta línea. El código llama directamente al archivo de recursos. Ejemplo: tengo un archivo llamado PageList.resx, luego llamaré: ResourceSet resourceSet = PageList.ResourceManager.GetResourceSet (CultureInfo.CurrentUICulture, true, true); – Gabriel

+0

@Gabriel, gracias por la actualización! Tendré que volver a mi código para verificarlo. – JoeFletch

7

Uso 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

blog acerca de que on my blog :) versión corta es, para encontrar los nombres completos de los recursos (a menos que ya los conoce):

var assembly = Assembly.GetExecutingAssembly(); 

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

Para utilizar todos ellos por algo:

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

Para utilizar recursos en otros ensambles que no sean el de ejecución, obtendría un objeto de ensamblaje diferente utilizando algunos de los otros métodos estáticos de la clase Assembly. Espero que ayude :)

+0

¿Puede enumerar los recursos * no * ubicados en una carpeta llamada 'Recurso'? Me gustaría enumerar todas las imágenes de recursos ubicadas en mi proyecto en una carpeta llamada 'Imágenes'. –

+0

¿Seguro que no le importa dónde está ubicado? ¿Pruébalo? – Svish

+1

Tenía archivos en una carpeta para importar archivos sql y esto funcionó perfectamente. Agregué una conversión de una secuencia a una cadena para poder leer el archivo y no tuve problemas. – ErocM

5

En el momento en que agrega un archivo .RESX de recursos a su proyecto, Visual Studio creará un Designer.cs con el mismo nombre, creando una clase para usted con todos los elementos del recurso como propiedades estáticas . Puede ver todos los nombres del recurso cuando escribe el punto en el editor después de escribir el nombre del archivo de recursos.

Como alternativa, puede utilizar la reflexión para recorrer estos nombres.

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 
} 

Este método obviamente solo se puede utilizar cuando el archivo RESX está dentro del alcance del ensamblaje o proyecto actual. De lo contrario, use el método proporcionado por "pulso".

La ventaja de este método es que llama a las propiedades reales que se le han proporcionado, teniendo en cuenta cualquier localización si lo desea. Sin embargo, es bastante redundante, ya que normalmente debería utilizar el método tipo safe direct para llamar a las propiedades de sus recursos. enlace

+2

¿Por qué usar la reflexión cuando hay un ResourceSet disponible? –

+0

Eso es lo que me pregunto también (ver el último párrafo). Solo quería mostrar un método alternativo, pero lo más importante, quería mostrar que la clase está completamente accesible y no es necesario que haga magia a mano (el primer párrafo). – 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(); 

véase: microsoft example

+3

Tenga en cuenta que esta clase se encuentra en el ensamblado 'System.Windows.Forms' y no se agrega automáticamente si está usando una aplicación MVC –

0

Usando LINQ to SQL:

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

Si desea utilizar LINQ, utilice resourceSet.OfType<DictionaryEntry>(). El uso de LINQ le permite, por ejemplo, para seleccionar los recursos en función de su índice (int) en lugar de la clave (cadena):

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