Локализация компонентов WinForms для OptionDialog

Автор Тема: Локализация компонентов WinForms для OptionDialog  (Прочитано 13294 раз)

0 Пользователей и 2 Гостей просматривают эту тему.

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Оффлайн avcАвтор темы

  • ADN Club
  • *****
  • Сообщений: 822
  • Карма: 166
    • Мои плагины к Автокаду
Некоторым пользователям удобно в английском Автокаде видеть русские диалоги настройки плагинов. Я создал локализованные компоненты WinForms, закинул их в один общий компонент OptionsCommonList (в нем уже локализация выключена ибо нет никаких своих ресурсов) и далее закидываю его в диалог настроек Автокада:
Код - C# [Выбрать]
  1.     private void Application_DisplayingOptionDialog(object sender, TabbedDialogEventArgs e)
  2.     {
  3.       CultureInfo old = Thread.CurrentThread.CurrentUICulture;
  4.       if (MySettings.UseWinLocale) // пользователь хочет диалоги на языке Windows, а не AutoСAD
  5.       {
  6.         CultureInfo win = Thread.CurrentThread.CurrentCulture;
  7.         if (old != win) Thread.CurrentThread.CurrentUICulture = win;
  8.       }
  9.       try
  10.       {
  11.         if (_CommonList == null) _CommonList = new OptionsCommonList();
  12.         TabbedDialogExtension tde = new TabbedDialogExtension(_CommonList, save, load, help, save);
  13.         e.AddTab("A>V>C>", tde);
  14.       }
  15.       finally
  16.       {
  17.         if (old != Thread.CurrentThread.CurrentUICulture)
  18.           Thread.CurrentThread.CurrentUICulture = old;
  19.       }
  20.     }
На моей Win7 все прекрасно работает. Но у пользователей с Win10 твориться полный бардак - компоненты переведены через строчку - часть на русском, часть на английском. На некоторых системах даже в русском Автокаде выводятся настройки по английски. А сегодня мне написали что и под Win7 не срабатывает перевод на русский.
Вопрос в том есть ли какой-то более корректный способ переключения языка у конкретного компонента WinForm? Свойство Language вижу в редакторе форм, но не вижу из кода (protected?)
Извините, вам запрещён просмотр содержимого спойлеров.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Думаю, что так ничего не получится. AutoCAD сам переопределяет Thread.CurrentThread.CurrentUICulture и Thread.CurrentThread.CurrentCulture. И в разных версиях это по-разному.
Если тебя интересует CultureInfo для Windows, то CultureInfo.InstalledUICulture
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Как вариант - можно попробовать напрямую подключать ресурсы для нужного языка: https://www.dotnetcurry.com/ShowArticle.aspx?ID=174

Оффлайн avcАвтор темы

  • ADN Club
  • *****
  • Сообщений: 822
  • Карма: 166
    • Мои плагины к Автокаду
Я видел, что у resources.ApplyResources есть параметр CultureInfo, но стандартный редактор форм его не использует. Писать свой код с вызовом ApplyResources для КАЖДОГО компонента форм - это пожалуй через чур сложно... Хотя можно попробовать... Спасибо за идею

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Писать свой код с вызовом ApplyResources для КАЖДОГО компонента форм - это пожалуй через чур сложно...
Я так понимаю, что вот эта функция из статьи применяет локализацию сразу ко всей форме:
Код - C# [Выбрать]
  1. private void ChangeLanguage(string lang)
  2.         {
  3.             foreach (Control c in this.Controls)
  4.             {
  5.                 ComponentResourceManager resources = new ComponentResourceManager(typeof(Form1));
  6.                 resources.ApplyResources(c, c.Name, new CultureInfo(lang));
  7.             }
  8.         }

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Вот ещё интересный код на эту тему: https://stackoverflow.com/a/10389737

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
avc,
Я правильно понимаю, что у тебя эта форма на двух языках (русский/английский)? В самом крайнем случае сделай две формы на двух языках и в зависимости от условия вызывай или одну или другую.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн avcАвтор темы

  • ADN Club
  • *****
  • Сообщений: 822
  • Карма: 166
    • Мои плагины к Автокаду
Я так понимаю, что вот эта функция из статьи применяет локализацию сразу ко всей форме:
Да, я именно это и попытался сделать:
Код - C# [Выбрать]
  1.     /// <summary>
  2.     /// Подменить язык текущего потока (Автокада) на язык Windows, если это настроено в AvcSettings.WinLocale
  3.     /// </summary>
  4.     internal static void Language(System.Windows.Forms.ContainerControl control)
  5.     {
  6.       if (!AvcSettings.WinLocale) return;
  7.       CultureInfo win = Thread.CurrentThread.CurrentCulture;
  8.       if (Thread.CurrentThread.CurrentUICulture == win) return;
  9.       ComponentResourceManager resources = new ComponentResourceManager(control.GetType());
  10.       ApplyResources(control.Controls, resources, win);
  11.     }
  12.  
  13.     /// <summary>
  14.     /// рекурсивный обход всех контролов
  15.     /// </summary>
  16.     private static void ApplyResources(ControlCollection controls, ComponentResourceManager resources, CultureInfo lng)
  17.     {
  18.       foreach (System.Windows.Forms.Control c in controls)
  19.       {
  20.         string t = c.Text;
  21.         resources.ApplyResources(c, c.Name, lng);
  22.         ApplyResources(c.Controls, resources, lng);
  23.       }
  24.     }
Пришлось повозиться, перелопачивать все компоненты и вставлять этот метод в конструктор после InitializeComponent. Но увы под Win7 у меня все заработало в таком варианте как и раньше работало. А под win10 метод ApplyResources тупо игнорируется. Проверяю c.Text - там как был английский так и остается, хотя lng передается русский.

Оффлайн avcАвтор темы

  • ADN Club
  • *****
  • Сообщений: 822
  • Карма: 166
    • Мои плагины к Автокаду
avc,
Я правильно понимаю, что у тебя эта форма на двух языках (русский/английский)? В самом крайнем случае сделай две формы на двух языках и в зависимости от условия вызывай или одну или другую.
Компоненты и формы где на 3-4 языках, но шаманства нужны только для русского, у остальных так и так латиница и им нет резона ставить английский Автокад. Плодить формы конечно вариант и конечно крайне неприятный... если только попытаться унаследовать....

Оффлайн avcАвтор темы

  • ADN Club
  • *****
  • Сообщений: 822
  • Карма: 166
    • Мои плагины к Автокаду
Вот ещё интересный код на эту тему: https://stackoverflow.com/a/10389737
Там ровно то же самое сделано - вызов ApplyResources для каждого контрола. И у них работает :(
p.s.
А! Так это 7 лет назад написано. Этой говнодесятки еще и в проекте не было :(

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
и вставлять этот метод в конструктор после InitializeComponent
Тут может быть проблема. Мне как-то нужно было принудительно перетащить форму в центр окна AutoCAD. Но автокадовский метод отрисовки диалога размещал его сам по своей логике. Пришлось задавать положение диалога в событии Activated формы. Подробнее - тут: http://adn-cis.org/forum/index.php?topic=7560.0
Возможно, что тут тоже идёт переназначение ресурсов внутренними методами AutoCAD уже после того, как отрабатывает InitializeComponent

Оффлайн avcАвтор темы

  • ADN Club
  • *****
  • Сообщений: 822
  • Карма: 166
    • Мои плагины к Автокаду
Я попробую конечно, но сомневаюсь. Проблема то не в том что ресурсы кто-то потом обатно переключает на английский, а в том что они вообще не хотят назначаться русские...

Отмечено как Решение avc 17-05-2019, 16:57:44

Оффлайн avcАвтор темы

  • ADN Club
  • *****
  • Сообщений: 822
  • Карма: 166
    • Мои плагины к Автокаду
Активации у компонентов нет, из OnLoad попробовал - бесполезно. Боюсь сглазить, но вроде заработал вызов из конструктора вот такого велосипеда:
Код - C# [Выбрать]
  1.     /// <summary>
  2.     /// Подменить язык текущего потока (Автокада) на язык Windows, если это настроено в AvcSettings.WinLocale
  3.     /// </summary>
  4.     internal static void Language(System.Windows.Forms.ContainerControl control)
  5.     {
  6.       if (!AvcSettings.WinLocale) return;
  7.       CultureInfo win = Thread.CurrentThread.CurrentCulture;
  8.       if (Thread.CurrentThread.CurrentUICulture == win) return;
  9.       CultureInfo old = Thread.CurrentThread.CurrentUICulture;
  10.       try
  11.       {
  12.         Thread.CurrentThread.CurrentUICulture = win;
  13.         ComponentResourceManager resources = new ComponentResourceManager(control.GetType());
  14.         ApplyResources(control.Controls, resources, win);
  15.       }
  16.       finally
  17.       {
  18.         Thread.CurrentThread.CurrentUICulture = old;
  19.       }
  20.     }
  21.  
  22.     /// <summary>
  23.     /// рекурсивный обход всех контролов
  24.     /// </summary>
  25.     private static void ApplyResources(ControlCollection controls, ComponentResourceManager resources, CultureInfo lng)
  26.     {
  27.       foreach (System.Windows.Forms.Control c in controls)
  28.       {
  29.         resources.ApplyResources(c, c.Name, lng);
  30.         ApplyResources(c.Controls, resources, lng);
  31.       }
  32.     }
Не могу утверждать, что это работает всегда ибо не понимаю почему на разных системах локализация работает по разному. Буду ждать откликов от пользователей.

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Я проверил на простом примере - у меня с локализацией WinForm никаких проблем нет. Windows 10 Rus, Civil 3D as AutoCAD 2019:

Тестовый проект прикладываю (VS 2019).
Локализацию делал по мануалу: https://docs.microsoft.com/en-us/previous-versions//y99d1cd3(v=vs.85)

Оффлайн avcАвтор темы

  • ADN Club
  • *****
  • Сообщений: 822
  • Карма: 166
    • Мои плагины к Автокаду
Чудеса да и только...  :-\