Domanda

Ho lavorato su un progetto di pet nei fine settimana per saperne di più su C # e ho incontrato un problema strano quando si lavora con la localizzazione. Per essere più precisi, il problema che ho è con System.Threading.Thread.CurrentThread.CurrentUICulture.

Ho impostato la mia app in modo che l'utente può cambiare rapidamente la lingua dell'applicazione facendo clic su una voce di menu. La voce di menu, a sua volta, salva il codice a due lettere per la lingua (ad esempio "en", "fr", etc.) in un ambiente utente chiamato 'Lingua' e poi riavvia l'applicazione.

Properties.Settings.Default.Language = "en";
Properties.Settings.Default.Save();
Application.Restart();

Quando l'applicazione viene avviata, la prima riga di codice nel costruttore del modulo (anche prima InitializeComponent ()) recupera la stringa di linguaggio dalle impostazioni e imposta il CurrentUICulture in questo modo:

public Form1()
{
    Thread.CurrentThread.CurrentUICulture = new CultureInfo(Properties.Settings.Default.Language);
    InitializeComponent();
}

La cosa è, questo non funziona in modo coerente. A volte, tutti funziona bene e l'applicazione viene caricata la lingua corretta in base alla stringa salvati nel file delle impostazioni. Altre volte, non è così, e la lingua rimane lo stesso dopo che l'applicazione viene riavviato.

In un primo momento ho pensato che non ha salvato la lingua prima di riavviare l'applicazione, ma che non è assolutamente il caso. Quando la lingua corretta non riesce a caricare, se dovessi chiudere l'applicazione ed eseguirlo di nuovo, la lingua corretta sarebbe venuto fuori in modo corretto. Quindi questo significa che la stringa lingua è stato salvato, ma l'assegnazione CurrentUICulture nel mio costruttore del form è senza alcun effetto a volte.

Qualsiasi aiuto? C'è qualcosa che mi manca di come filettatura opere in C #? Questo potrebbe essere specifico per il computer, quindi se fa alcuna differenza che sto utilizzando Pentium Dual-Core CPU.

Aggiorna

Vlad mi ha chiesto di controllare ciò che CurrentUICulture del CurrentThread è. Così ho aggiunto un MessageBox sul mio costruttore per dirmi che cosa il CurrentUICulture codice di due lettere è così come il valore della mia stringa user lingua.

MessageBox.Show(string.Format("Current Language: {0}\nCurrent UI Culture: {1}", Properties.Settings.Default.Language, Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName));

Quando la lingua errata viene caricata, sia la stringa lingua e CurrentUICulture hanno la lingua sbagliata. Quindi credo che la CurrentUICulture è stato eliminato e il mio problema è in realtà con l'impostazione della lingua.

Quindi credo che il problema è che la mia applicazione a volte carica la stringa di linguaggio precedentemente salvato, piuttosto che l'ultima stringa di lingua salvata. Se l'applicazione viene riavviato, verrà quindi caricare la stringa di lingua salvata reale.

È stato utile?

Soluzione

ho avuto lo stesso problema. Ho capito che Application.Restart () in realtà non fanno assolutamente riavvio, vedere MSDN .

Application.Restart () non chiamare le cose inizializzazione all'interno del costruttore forme come InitializeComponent (), più le "Applicazioni vengono riavviati nel contesto in cui sono stati inizialmente eseguiti".

Quindi, il codice è corretto

Properties.Settings.Default.Language = "en";
Properties.Settings.Default.Save();

public Form1()
{
    Thread.CurrentThread.CurrentUICulture = new CultureInfo(Properties.Settings.Default.Language);
    //...
    InitializeComponent();
}

, ma non funziona in questo modo con Application.Restart(). Se si chiude l'applicazione e aprire di nuovo la tua (nuovi) impostazioni vengono prese.

Quindi dobbiamo trovare un modo per inizializzare di nuovo il modulo per rendere le nuove impostazioni della lingua accadere.

Altri suggerimenti

Può controllare qual è CurrentUICulture del tuo thread?

Mi ricordo di avere un problema come la vostra; è stato risolto ricaricando il dizionario risorse contenente le stringhe di essere localizzati:

Thread.CurrentThread.CurrentUICulture = <new culture>;
ResourceDictionary newDict = new ResourceDictionary();
newDict.Source = localizedStrings.Source;
localizedStrings = newDict;

(e questo approccio ha funzionato in modo dinamico pure; qui è qualche informazione in più).

Si potrebbe modificare manualmente la lingua del modulo corrente simile a questo:

CultureInfo cInfo = new CultureInfo("en-US");
ResourceManager rm = new ResourceManager(GetType());

// For each control on the form, perform the translation manually (probably better in a loop)
control1.Text = rm.GetString(control1.Name + ".Text", cInfo);

// Now set the culture for all other dialogs
Thread.CurrentThread.CurrentUICulture = cInfo;

Speranza che aiuta!

Si potrebbe semplicemente "reset" l'applicazione chiudendo le forme aperte e ri-crearli. Quindi è possibile impostare direttamente la cultura quando l'utente modifica l'impostazione.

Inoltre, provare a dare un po 'di output di debug in modo da vedere quali valori sono in corso set e se la cultura è in realtà quello che ci si aspetta.

EDIT: La mia ipotesi:. Dal momento che i dati devono essere scritti in un file, e poi caricato da quel file, si può essere riavvia troppo in fretta che la scrittura sia stato completato

Utilizzando CurrentThread.CurrentUICulture, e quindi modificando il modulo, non è necessario riavviare l'applicazione. Rif mio vecchio post qui

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top