2010-01-11 10 views
111

Existe-t-il un moyen de parcourir toutes les ressources d'un fichier .resx en C#?Parcourez toutes les ressources d'un fichier .resx

+1

Pouvez-vous préciser si le fichier RESX interne à votre projet ou si vous voulez (ou besoin de) lire un fichier RESX séparé ou lire RESX d'un autre assemblage? – Abel

Répondre

211

Vous devez toujours utiliser le gestionnaire de ressources et ne pas lire directement les fichiers pour vous assurer que la globalisation est prise en compte.

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

Il m'a fallu un peu de comprendre que vous avez besoin de cette ligne pour déclarer MyResourceClass. 'ResourceManager MyResourceClass = nouveau ResourceManager (" Resources.ResourceFileName ", System.Reflection.Assembly.Load (" App_GlobalResources "));' – JoeFletch

+6

@JoeFletch: il n'a pas besoin de cette ligne. Le code appelle directement le fichier de ressources. Exemple: j'ai un fichier nommé PageList.resx, puis j'appelle: ResourceSet resourceSet = PageList.ResourceManager.GetResourceSet (CultureInfo.CurrentUICulture, true, true); – Gabriel

+0

@Gabriel, merci pour la mise à jour! Je vais devoir revenir à mon code pour vérifier cela. – JoeFletch

7

Utilisez 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

blogué sur ce on my blog :) version courte est, pour trouver le nom complet des ressources (sauf si vous les connaissez déjà):

var assembly = Assembly.GetExecutingAssembly(); 

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

Pour utiliser tous pour quelque chose:

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

Pour utiliser les ressources dans d'autres ensembles que l'exécution d'une, nous aurions tout simplement un objet de montage différent en utilisant quelques-unes des autres méthodes statiques de la classe Assembly. J'espère que ça aide :)

+0

Pouvez-vous énumérer les ressources * non * situées dans un dossier appelé «Ressource»? Je voudrais énumérer toutes les images de ressource situées dans mon projet dans un dossier appelé «Images». –

+0

À peu près sûr que ça ne l'intéresse pas? Essaye-le? – Svish

+1

J'ai eu des fichiers dans un dossier pour inporting sql fichiers et cela a fonctionné parfaitement. J'ai ajouté une conversion d'un flux à la chaîne afin que je puisse lire le fichier et n'ai eu aucun problème. – ErocM

5

La minute où vous ajoutez un fichier de ressources .RESX à votre projet, Visual Studio crée un Designer.cs du même nom, en créant une classe pour vous avec tous les éléments de la ressource en tant que propriétés statiques . Vous pouvez voir tous les noms de la ressource lorsque vous tapez le point dans l'éditeur après avoir tapé le nom du fichier de ressources.

Vous pouvez également utiliser la réflexion pour parcourir ces noms.

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 
} 

Cette méthode est évidemment uniquement utilisable lorsque le fichier RESX est dans la portée de l'assemblage ou du projet en cours. Sinon, utilisez la méthode fournie par "pulse".

L'avantage de cette méthode est que vous appelez les propriétés réelles qui ont été fournies pour vous, en tenant compte de toute localisation si vous le souhaitez. Cependant, il est plutôt redondant, car normalement vous devriez utiliser la méthode directe d'appel de sécurité des types de vos ressources.

+2

Pourquoi utiliser la réflexion lorsqu'un ResourceSet est disponible? –

+0

C'est ce que je me demande aussi (voir le dernier paragraphe). Je voulais juste montrer une méthode alternative, mais plus important encore, je voulais montrer que la classe est rendue entièrement accessible et que vous n'avez pas besoin de faire de la magie à la main (le premier paragraphe). – 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(); 

voir le lien: microsoft example

+3

Notez que cette classe se trouve dans l'assembly 'System.Windows.Forms' et n'est pas ajoutée automatiquement si vous utilisez une application MVC –

0

En utilisant LINQ to SQL:

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

Si vous souhaitez utiliser LINQ, utilisez resourceSet.OfType<DictionaryEntry>(). LINQ vous permet, par exemple, de sélectionner des ressources en fonction de leur index (int) au lieu de la clé (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); 
}