Czy możesz wyjaśnić, czy plik RESX jest wewnętrzny dla twojego projektu, czy też chcesz (lub musisz) odczytać oddzielny plik RESX lub odczytać RESX z innego zespołu?
Abel
Odpowiedzi:
243
Należy zawsze używać menedżera zasobów i nie czytać plików bezpośrednio, aby mieć pewność, że brana jest pod uwagę globalizacja.
using System.Collections;
using System.Globalization;
using System.Resources;
...
/* Reference to your resources class -- may be named differently in your case */ResourceManagerMyResourceClass=newResourceManager(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;}
Trochę zajęło mi ustalenie, że potrzebujesz tego wiersza do zadeklarowania MyResourceClass. ResourceManager MyResourceClass = new ResourceManager("Resources.ResourceFileName", System.Reflection.Assembly.Load("App_GlobalResources"));
JoeFletch
6
@JoeFletch: nie potrzebuje tej linii. Kod bezpośrednio wywołuje plik zasobów. Przykład: mam plik o nazwie PageList.resx, wtedy zadzwonię: ResourceSet resourceSet = PageList.ResourceManager.GetResourceSet (CultureInfo.CurrentUICulture, true, true);
Gabriel
@Gabriel, dzięki za aktualizację! Będę musiał wrócić do swojego kodu, aby to sprawdzić.
JoeFletch
3
Linia JoeFletcha faktycznie mi pomogła. Miałem resx znajdujący się w innym projekcie C #, więc jego linia pozwoliła mi wywołać ten zestaw dll i załadować zasoby w ten sposób. Ponadto, gdy próbowałem dołączyć PageList do mojego kodu, generował błąd dla PageList.ResourceManager .. mówiąc, że „PageList nie zawiera definicji dla ResourceManager”. I wreszcie string resourceKey = entry.Key wyrzucił błąd, zamiast tego użyłem „object resourceKey = entry.Key”
sksallaj
2
W zależności od tego, czy faktycznie masz zdefiniowane kultury w swoim zasobie, będziesz musiał przełączyć się do CultureInfo.InvariantCulture. Tutaj używałem zasobów w bibliotece, a nie aplikacji WinForms.
Israel Lopez
26
Blogowałem o tym na swoim blogu :) Krótka wersja to, aby znaleźć pełne nazwy zasobów (chyba, że już je znasz):
var assembly =Assembly.GetExecutingAssembly();foreach(var resourceName in assembly.GetManifestResourceNames())System.Console.WriteLine(resourceName);
Aby użyć ich wszystkich do czegoś:
foreach(var resourceName in assembly.GetManifestResourceNames()){
using(var stream = assembly.GetManifestResourceStream(resourceName)){// Do something with stream}}
Aby użyć zasobów w innych zestawach niż wykonujący, wystarczy uzyskać inny obiekt zestawu przy użyciu niektórych innych metod statycznych Assemblyklasy. Mam nadzieję, że to pomoże :)
Czy potrafisz wyliczyć zasoby, które nie znajdują się w folderze o nazwie „Zasób”? Chciałbym wyliczyć wszystkie obrazy zasobów znajdujące się w moim projekcie w folderze o nazwie „Obrazy”.
Simon Bosley
Na pewno nie dba o to, gdzie się znajduje? Sprawdź to?
Svish
1
Miałem pliki w folderze do inportowania plików sql i to działało idealnie. Dodałem konwersję ze strumienia do ciągu, dzięki czemu mogłem odczytać plik i nie miałem żadnych problemów.
ResXResourceReader rsxr =newResXResourceReader("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());}
// Create a ResXResourceReader for the file items.resx.ResXResourceReader rsxr =newResXResourceReader("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();
Zwróć uwagę, że ta klasa znajduje się w System.Windows.Formszestawie i nie jest automatycznie dodawana, jeśli używasz aplikacji MVC
Rob Scott
6
W chwili dodania pliku .RESX zasobu do projektu program Visual Studio utworzy plik Designer.cs o tej samej nazwie, tworząc dla Ciebie klasę ze wszystkimi elementami zasobu jako właściwościami statycznymi. Wszystkie nazwy zasobów można wyświetlić, wpisując kropkę w edytorze po wpisaniu nazwy pliku zasobów.
Alternatywnie możesz użyć odbicia, aby zapętlić te nazwy.
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;objectvalue= info.GetValue(null,null);// object can be an image, a string whatever// do something with name and value}
Ta metoda jest oczywiście używana tylko wtedy, gdy plik RESX znajduje się w zakresie bieżącego zestawu lub projektu. W przeciwnym razie użyj metody zapewnianej przez „puls”.
Zaletą tej metody jest to, że wywołujesz rzeczywiste właściwości, które zostały dla Ciebie dostarczone, biorąc pod uwagę dowolną lokalizację, jeśli chcesz. Jest to jednak raczej zbędne, ponieważ normalnie powinieneś używać bezpośredniej metody typu safe do wywoływania właściwości zasobów.
Po co używać odbicia, gdy dostępny jest zestaw zasobów?
Oundless
To jest to, co też bym się zastanawiał (patrz ostatni akapit). Chciałem tylko pokazać alternatywną metodę, ale co ważniejsze, chciałem pokazać, że klasa jest w pełni dostępna i nie musisz wykonywać żadnej magii ręcznie (pierwszy akapit).
Jeśli chcesz używać LINQ, użyj resourceSet.OfType<DictionaryEntry>(). Korzystanie z LINQ pozwala na przykład wybierać zasoby na podstawie ich indeksu (int) zamiast klucza (string):
var resx =ResourcesName.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture,false,false);foreach(DictionaryEntry dictionaryEntry in resx){Console.WriteLine("Key: "+ dictionaryEntry.Key);Console.WriteLine("Val: "+ dictionaryEntry.Value);}
Odpowiedzi:
Należy zawsze używać menedżera zasobów i nie czytać plików bezpośrednio, aby mieć pewność, że brana jest pod uwagę globalizacja.
...
źródło
ResourceManager MyResourceClass = new ResourceManager("Resources.ResourceFileName", System.Reflection.Assembly.Load("App_GlobalResources"));
Blogowałem o tym na swoim blogu :) Krótka wersja to, aby znaleźć pełne nazwy zasobów (chyba, że już je znasz):
Aby użyć ich wszystkich do czegoś:
Aby użyć zasobów w innych zestawach niż wykonujący, wystarczy uzyskać inny obiekt zestawu przy użyciu niektórych innych metod statycznych
Assembly
klasy. Mam nadzieję, że to pomoże :)źródło
Użyj klasy ResXResourceReader
źródło
zobacz link: przykład firmy Microsoft
źródło
System.Windows.Forms
zestawie i nie jest automatycznie dodawana, jeśli używasz aplikacji MVCW chwili dodania pliku .RESX zasobu do projektu program Visual Studio utworzy plik Designer.cs o tej samej nazwie, tworząc dla Ciebie klasę ze wszystkimi elementami zasobu jako właściwościami statycznymi. Wszystkie nazwy zasobów można wyświetlić, wpisując kropkę w edytorze po wpisaniu nazwy pliku zasobów.
Alternatywnie możesz użyć odbicia, aby zapętlić te nazwy.
Ta metoda jest oczywiście używana tylko wtedy, gdy plik RESX znajduje się w zakresie bieżącego zestawu lub projektu. W przeciwnym razie użyj metody zapewnianej przez „puls”.
Zaletą tej metody jest to, że wywołujesz rzeczywiste właściwości, które zostały dla Ciebie dostarczone, biorąc pod uwagę dowolną lokalizację, jeśli chcesz. Jest to jednak raczej zbędne, ponieważ normalnie powinieneś używać bezpośredniej metody typu safe do wywoływania właściwości zasobów.
źródło
Możesz użyć ResourceManager.GetResourceSet .
źródło
Jeśli chcesz używać LINQ, użyj
resourceSet.OfType<DictionaryEntry>()
. Korzystanie z LINQ pozwala na przykład wybierać zasoby na podstawie ich indeksu (int) zamiast klucza (string):źródło
W przypadku pakietu
System.Resources.ResourceManager
NuGet (wersja 4.3.0)ResourceSet
iResourceManager.GetResourceSet
nie są dostępne.Używając
ResourceReader
, jak sugeruje ten post: „ C # - Nie można pobrać ciągu z ResourceManager (z zestawu satelickiego) ”Nadal można odczytać klucze / wartości pliku zasobów.
źródło
Korzystanie z LINQ to SQL :
źródło
Prosta pętla odczytu używa tego kodu
źródło