Thread.CurrentThread.CurrentUICulture не работает последовательно - PullRequest
0 голосов
/ 28 апреля 2010

В выходные я работал над любимым проектом, чтобы узнать больше о C #, и столкнулся со странной проблемой при работе с локализацией. Чтобы быть более конкретным, у меня проблема с System.Threading.Thread.CurrentThread.CurrentUICulture.

Я настроил свое приложение так, чтобы пользователь мог быстро изменить язык приложения, щелкнув пункт меню. Пункт меню, в свою очередь, сохраняет двухбуквенный код для языка (например, «en», «fr» и т. Д.) В пользовательской настройке «Language», а затем перезапускает приложение.

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

Когда приложение запускается, первая строка кода в конструкторе формы (даже до InitializeComponent ()) выбирает строку языка из настроек и устанавливает CurrentUICulture следующим образом:

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

Дело в том, что это не работает последовательно. Иногда все работает хорошо, и приложение загружает правильный язык на основе строки, сохраненной в файле настроек. В других случаях это не так, и язык остается тем же после перезапуска приложения.

Сначала я подумал, что не сохранял язык до перезапуска приложения, но это определенно не тот случай. Когда не удается загрузить правильный язык, если бы я должен был закрыть приложение и запустить его снова, правильный язык был бы найден правильно. Таким образом, это означает, что строка Language была сохранена, но назначение CurrentUICulture в моем конструкторе формы иногда не оказывает никакого влияния.

Любая помощь? Есть ли что-то, чего мне не хватает, как работает многопоточность в C #? Это может зависеть от конкретной машины, поэтому, если будет какая-то разница, я использую двухъядерный процессор Pentium.

UPDATE

Влад попросил меня проверить, какова текущая культура CurrentThread. Поэтому я добавил MessageBox на свой конструктор, чтобы сообщить мне, что такое двухбуквенный код CurrentUICulture, а также значение моей пользовательской строки Language.

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

Когда загружен неправильный язык, строка языка и CurrentUICulture имеют неправильный язык. Так что я думаю, что CurrentUICulture был очищен, и моя проблема на самом деле связана с настройкой языка.

Так что, я думаю, проблема в том, что мое приложение иногда загружает ранее сохраненную языковую строку, а не последнюю сохраненную языковую строку. Если приложение перезапустится, оно загрузит текущую сохраненную языковую строку.

Ответы [ 5 ]

3 голосов
/ 20 августа 2010

У меня такая же проблема. Я понял, что Application.Restart () на самом деле не делает абсолютно перезапуск, см. MSDN .

Поэтому Application.Restart () не вызывает инициализирующие вещи в конструкторе форм. подобно InitializeComponent (), более «Приложения перезапускаются в контексте, в котором они были изначально запущены».

Итак, ваш код правильный

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

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

но это не работает с Application.Restart(). Если вы закроете приложение и снова откроете его, ваши (новые) настройки будут приняты.

Таким образом, мы должны найти способ снова инициализировать форму, чтобы новые настройки языка произошли.

1 голос
/ 25 октября 2012

Вы можете вручную изменить язык текущей формы следующим образом:

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;

Надеюсь, это поможет!

1 голос
/ 28 апреля 2010

Не могли бы вы проверить, что у вашей темы CurrentUICulture?

Я помню, как у меня была такая проблема; это было решено путем перезагрузки словаря ресурсов, содержащего строки для локализации:

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

(и этот подход также работал динамически; здесь - дополнительная информация).

0 голосов
/ 27 октября 2010

Используя CurrentThread.CurrentUICulture и затем изменяя форму, вам не нужно перезапускать приложение. Ref мой старый пост здесь

0 голосов
/ 28 апреля 2010

Вы можете просто «сбросить» свое приложение, закрыв открытые формы и воссоздав их. Тогда вы можете напрямую установить культуру, когда пользователь изменит настройку.

Кроме того, попробуйте дать некоторые выходные данные для отладки, чтобы увидеть, какие значения устанавливаются и соответствует ли культура тому, что вы ожидаете.

РЕДАКТИРОВАТЬ: мое предположение: поскольку данные должны быть записаны в файл, а затем загружены из этого файла, вы можете перезапускать слишком быстро, чтобы запись была завершена.

...