Bir .resx dosyasındaki tüm kaynaklar arasında döngü yapın


126

.resxC # 'da bir dosyadaki tüm kaynaklar arasında döngü yapmanın bir yolu var mı ?


2
RESX dosyasının projenize dahil olup olmadığını veya ayrı bir RESX dosyası okumak veya başka bir derlemeden RESX okumak isteyip istemediğinizi (veya gerekip gerekmediğini) detaylandırabilir misiniz?
Abel

Yanıtlar:


243

Globalleşmenin hesaba katılmasını sağlamak için her zaman kaynak yöneticisini kullanmalı ve dosyaları doğrudan okumamalısınız.

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

...

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

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'ı bildirmek için bu satıra ihtiyacınız olduğunu anlamam biraz zaman aldı. ResourceManager MyResourceClass = new ResourceManager("Resources.ResourceFileName", System.Reflection.Assembly.Load("App_GlobalResources"));
JoeFletch

6
@JoeFletch: Bu satıra ihtiyacı yok. Kod doğrudan Kaynak Dosyasını çağırır. Örnek: PageList.resx adında bir dosyam var, sonra şunu arayacağım: ResourceSet resourceSet = PageList.ResourceManager.GetResourceSet (CultureInfo.CurrentUICulture, true, true);
Gabriel

@Gabriel, güncelleme için teşekkürler! Bunu kontrol etmek için koduma geri dönmem gerekecek.
JoeFletch

3
JoeFletch'in çizgisi aslında bana yardımcı oldu. Başka bir C # projesinde bulunan bir resxim vardı, bu yüzden onun satırı o dll derlemesini çağırmama ve kaynakları bu şekilde yüklememe izin verdi. Ayrıca, PageList'i koduma dahil etmeye çalıştığımda, PageList.ResourceManager için bir hata verdi .. "PageList, ResourceManager için bir tanım içermiyor" diyerek. Ve son olarak, resourceKey = entry.Key string bir hata attı, onun yerine "object resourceKey = entry.Key" kullandım
sksallaj

2
Kaynağınızda tanımlanmış kültürleriniz olup olmadığına bağlı olarak, CultureInfo.InvariantCulture'a geçmeniz gerekecektir. Burada kaynakları bir WinForms uygulaması değil, bir kütüphanede kullanıyordum.
Israel Lopez

26

Blogumda bununla ilgili blog yazdım :) Kısa versiyon, kaynakların tam adlarını bulmak için (zaten bilmiyorsanız):

var assembly = Assembly.GetExecutingAssembly();

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

Hepsini bir şey için kullanmak için:

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

Kaynakları yürütmekten başka derlemelerde kullanmak için, Assemblysınıfın diğer statik yöntemlerinden bazılarını kullanarak farklı bir derleme nesnesi elde edersiniz . Umarım yardımcı olur :)


Eğer kaynak numaralandırabilir değil 'Kaynak' adlı bir klasörde bulunan? Projemde bulunan tüm kaynak görüntülerini 'Görüntüler' adlı bir klasörde numaralandırmak istiyorum.
Simon Bosley

Nerede olduğunun umurunda olmadığına emin misin? Dene?
Svish

1
Sql dosyalarını içe aktarmak için bir klasörde dosyalarım vardı ve bu mükemmel çalıştı. Bir akıştan dizeye bir dönüşüm ekledim, böylece dosyayı okuyabilirdim ve sorun yaşamadım.
ErocM

9

ResXResourceReader Sınıfını Kullanın

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

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

bağlantıya bakın: microsoft örneği


4
Bu sınıfın System.Windows.Formsderlemede olduğunu ve bir MVC uygulaması kullanıyorsanız otomatik olarak eklenmediğini unutmayın
Rob Scott

6

Projenize bir kaynak .RESX dosyası eklediğiniz dakika, Visual Studio aynı ada sahip bir Designer.cs oluşturarak sizin için statik özellikler olarak kaynağın tüm öğeleriyle bir sınıf oluşturur. Kaynak dosyasının adını yazdıktan sonra düzenleyicide noktayı yazdığınızda kaynağın tüm adlarını görebilirsiniz.

Alternatif olarak, bu isimler arasında döngü yapmak için yansımayı kullanabilirsiniz.

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
}

Bu yöntem açıkça yalnızca RESX dosyası geçerli derleme veya proje kapsamında olduğunda kullanılabilir. Aksi takdirde, "darbe" ile sağlanan yöntemi kullanın.

Bu yöntemin avantajı, dilerseniz herhangi bir yerelleştirmeyi hesaba katarak, sizin için sağlanan gerçek mülkleri aramanızdır. Ancak, normalde kaynaklarınızın özelliklerini çağırmak için type safe direct yöntemini kullanmanız gerektiğinden, oldukça fazladır.


2
Bir ResourceSet varken neden yansımayı kullanalım?
Oundless

Ben de merak ettiğim şey bu (son paragrafa bakın). Sadece alternatif bir yöntem göstermek istedim, ama daha da önemlisi, sınıfın tamamen erişilebilir olduğunu ve elle herhangi bir sihir yapmanıza gerek olmadığını (ilk paragraf) göstermek istedim.
Abel


1

LINQ kullanmak istiyorsanız, kullanın resourceSet.OfType<DictionaryEntry>(). LINQ kullanmak, örneğin, anahtar (dize) yerine dizinlerine (int) göre kaynakları seçmenize olanak tanır:

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

1

NuGet paketi System.Resources.ResourceManager(v4.3.0) ile ResourceSetveResourceManager.GetResourceSet kullanılamaz.

Kullanımı ResourceReaderbu yazı olarak, önermek: " C # - (montaj uydudan) ResourceManager bir dize almıyor Can "

Kaynak dosyasının anahtar / değerlerinin okunması hala mümkündür.

System.Reflection.Assembly resourceAssembly = System.Reflection.Assembly.Load(new System.Reflection.AssemblyName("YourAssemblyName"));
String[] manifests = resourceAssembly.GetManifestResourceNames(); 
using (ResourceReader reader = new ResourceReader(resourceAssembly.GetManifestResourceStream(manifests[0])))
{
   System.Collections.IDictionaryEnumerator dict = reader.GetEnumerator();
   while (dict.MoveNext())
   {
      String key = dict.Key as String;
      String value = dict.Value as String;
   }
}

0

LINQ to SQL'i kullanma :

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

0

Basit okuma döngüsü bu kodu kullanır

var resx = ResourcesName.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, false, false);

foreach (DictionaryEntry dictionaryEntry in resx)
{
    Console.WriteLine("Key: " + dictionaryEntry.Key);
    Console.WriteLine("Val: " + dictionaryEntry.Value);
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.