2009-02-16 12 views
22

Sto progettando un'applicazione multilingue utilizzando i file .resx.Modo programmatico per ottenere tutte le lingue disponibili (negli assembly satellite)

Ho alcuni file come GlobalStrings.resx, GlobalStrings.es.resx, GlobalStrings.en.resx, ecc. Quando voglio utilizzare questo, ho solo bisogno di impostare Thread.CurrentThread.CurrentCulture.

Il problema: Ho un combobox con tutte le lingue disponibili, ma io sono il caricamento di questo manuale:

comboLanguage.Items.Add(CultureInfo.GetCultureInfo("en")); 
comboLanguage.Items.Add(CultureInfo.GetCultureInfo("es")); 

Ho provato con

cmbLanguage.Items.AddRange(CultureInfo.GetCultures(CultureTypes.UserCustomCulture)); 

senza alcun successo. Ho provato anche con tutti gli elementi in CultureTypes, ma sto ottenendo solo una grande lista con molte più lingue che non sto usando, o una lista vuota.

C'è un modo per ottenere solo le lingue supportate?

risposta

1

Utilizzando quello Rune Grimstad detto io alla fine con questo:

string executablePath = Path.GetDirectoryName(Application.ExecutablePath); 
string[] directories = Directory.GetDirectories(executablePath); 
foreach (string s in directories) 
{ 
    try 
    { 
     DirectoryInfo langDirectory = new DirectoryInfo(s); 
     cmbLanguage.Items.Add(CultureInfo.GetCultureInfo(langDirectory.Name)); 
    } 
    catch (Exception) 
    { 

    } 
} 

modo o nell'altro

int pathLenght = executablePath.Length + 1; 
foreach (string s in directories) 
{ 
    try 
    { 
     cmbLanguage.Items.Add(CultureInfo.GetCultureInfo(s.Remove(0, pathLenght))); 
    } 
    catch (Exception) 
    { 

    } 
} 

Continuo a non pensare che questa sia una buona idea ...

+0

Penso che questa sia l'unica soluzione che abbiamo ottenuto. Sono nella stessa barca. – Jippers

+0

Questo non otterrebbe anche le directory di risorse che le dipendenze dispiegate (se presenti)? Quindi potresti finire con alcune culture che non supportano ma alcune delle tue dipendenze. –

2

Non sono sicuro di ottenere le lingue, forse è possibile eseguire la scansione della cartella di installazione per i file dll, ma impostare la lingua in una lingua non supportata non dovrebbe essere un problema.

.NET eseguirà il fallback delle risorse culture neutral se non è possibile trovare file specifici della cultura in modo da poter selezionare in modo sicuro le lingue non supportate.

Finché si controlla l'applicazione da soli, è possibile memorizzare le lingue disponibili in un'applicazione in qualche punto. Basta una stringa separata da virgole con i nomi della cultura dovrebbe essere sufficiente: "en, es"

37

È possibile elencare in modo programmatico le colture disponibili nell'applicazione

// Pass the class name of your resources as a parameter e.g. MyResources for MyResources.resx 
ResourceManager rm = new ResourceManager(typeof(MyResources)); 

CultureInfo[] cultures = CultureInfo.GetCultures(CultureTypes.AllCultures); 
foreach (CultureInfo culture in cultures) 
{ 
    try 
    { 
     ResourceSet rs = rm.GetResourceSet(culture, true, false); 
     // or ResourceSet rs = rm.GetResourceSet(new CultureInfo(culture.TwoLetterISOLanguageName), true, false); 
     string isSupported = (rs == null) ? " is not supported" : " is supported"; 
     Console.WriteLine(culture + isSupported); 
    } 
    catch (CultureNotFoundException exc) 
    { 
     Console.WriteLine(culture + " is not available on the machine or is an invalid culture identifier."); 
    } 
} 
+0

Si noti che 'GlobalStrings.resx' verrà rilevato in' InvariantCulture'. – Hans

+5

Questa forza non caricherà essenzialmente tutti i gruppi satellite? –

+0

@TaylorBuchanan potrebbe probabilmente chiamare ReleaseAllResources successivamente (https://msdn.microsoft.com/en-us/library/system.resources.resourcemanager.releaseallresources(v=vs.110).aspx) e quindi caricare nuovamente la risorsa specifica –

1

in base alla risposta da @ hans-holzbart ma fisso di non restituire l'InvariantCulture troppo e avvolto in un metodo riutilizzabile:

public static IEnumerable<CultureInfo> GetAvailableCultures() 
{ 
    List<CultureInfo> result = new List<CultureInfo>(); 

    ResourceManager rm = new ResourceManager(typeof(Resources)); 

    CultureInfo[] cultures = CultureInfo.GetCultures(CultureTypes.AllCultures); 
    foreach (CultureInfo culture in cultures) 
    { 
    try 
    { 
     if (culture.Equals(CultureInfo.InvariantCulture)) continue; //do not use "==", won't work 

     ResourceSet rs = rm.GetResourceSet(culture, true, false); 
     if (rs != null) 
     result.Add(culture); 
    } 
    catch (CultureNotFoundException) 
    { 
     //NOP 
    } 
    } 
    return result; 
} 

utilizzando tale metodo, è possibile ottenere una lista di stringhe da aggiungere al alcune ComboBox con la seguente:

public static ObservableCollection<string> GetAvailableLanguages() 
{ 
    var languages = new ObservableCollection<string>(); 
    var cultures = GetAvailableCultures(); 
    foreach (CultureInfo culture in cultures) 
    languages.Add(culture.NativeName + " (" + culture.EnglishName + " [" + culture.TwoLetterISOLanguageName + "])"); 
    return languages; 
} 
4

Questa sarebbe una delle soluzioni sulla base della seguente dichiarazione:
Ogni assembly satellite per una lingua specifica è chiamato lo stesso, ma si trova in una sottocartella che prende il nome dalla cultura specifica, ad es. fr o fr-CA.

public IEnumerable<CultureInfo> GetSupportedCulture() 
{ 
    //Get all culture 
    CultureInfo[] culture = CultureInfo.GetCultures(CultureTypes.AllCultures); 

    //Find the location where application installed. 
    string exeLocation = Path.GetDirectoryName(Uri.UnescapeDataString(new UriBuilder(Assembly.GetExecutingAssembly().CodeBase).Path)); 

    //Return all culture for which satellite folder found with culture code. 
    return culture.Where(cultureInfo => Directory.Exists(Path.Combine(exeLocation, cultureInfo.Name))); 
} 
+1

Questa soluzione funziona sul mio progetto ASP.net MVC. Grazie !! –

+0

@JeffT. Sì, è molto generico, ho usato questo approccio per il nostro progetto WPF! –

+0

Si prega di notare che questo restituirà anche la lingua invariante. – ooorndtski

Problemi correlati