Локализация приложения WinForms со встроенными пользовательскими элементами управления WPF

Приложение, которое я пытаюсь локализовать, является приложением WinForms, которое имеет несколько размещенных пользовательских элементов управления WPF (пользовательских элементов управления WPF, размещенных в элементе управления ElementHost WinForms).

Я использую файлы resx для локализации WinForms, с которыми VS2008 справляется довольно хорошо.

Проблема начинается, когда я пытаюсь использовать метод LocBaml для локализации частей WPF.

Вот что происходит: когда я создаю решение, Visual Studio автоматически генерирует спутниковые сборки для меня, но только для ресурсов WinForms в файлах resx. Затем, когда я использую инструмент командной строки LocBaml, он генерирует спутниковые сборки для меня, но только для ресурсов WPF в файлах xaml.

Я не понял, как объединить две полученные библиотеки DLL (WPF и WinForms) в одну спутниковую сборку.

3 ответа

Blech... Команда WPF, похоже, оставила желать лучшего с их решением по локализации. Ну, для чего это стоит, вот что я делал (честно говоря, я фактически позаимствовал эту идею у Jecho Jekov в CodeProject):

Во-первых, вам нужно создать (или позаимствовать) класс Localization MarkupExtension. Джечо называет свой LocExtension, я назвал свой i18nExtension ни по какой другой причине, кроме того, что мне показалось, что это немного более наглядно, чем Loc. Это расширение разметки будет выполнять поиск заданного ключа ресурса в файле ресурсов. Это действительно простой и легкий класс для написания кода, если вы хотите, чтобы все ваши ресурсы находились в файле Properties/Resources.resx.

В результате вы получите что-то вроде этого в вашем xaml:

<UserControl ... >
    ...
    <TextBox Text="{i18n HelloWorld}"/>
    ...
</UserControl>

Если вы хотите иметь отдельные файлы resx для каждого элемента UserControl/Window, как позволяет конструктор WinForms, вам нужно проявить немного больше креативности в MarkupExtension, чтобы он мог выяснить свой контекст.

В конечном счете, вы получаете одну сборку сателлитов на культуру, что, как вам кажется, и после. Единственное предостережение, которое приходит на ум, заключается в том, что я не уверен, как это происходит с изменениями культуры / языка на лету. По крайней мере, Window/Control нужно будет перезагрузить.

Как объединить несколько наборов ресурсов в одну спутниковую сборку

Правильный метод состоит в том, чтобы использовать AL.exe (средство компоновки сборок) для встраивания файла формы Windows.resources и.resources, сгенерированных LocBaml, в одну вспомогательную сборку (заменяя исходную сборку по умолчанию, содержащую только ресурсы WinForms).

Шаги для создания гибридного приложения будут:

  1. Создайте свое решение (создание файла.resource только для WinForms и спутниковой библиотеки DLL).
  2. Создайте свой XAML .resource файл, используя инструмент locBaml
  3. Используйте AL.exe, чтобы связать оба набора файлов.resource в новую гибридную сателлитную DLL и заменить оригинал с шага 1. Для перестройки проекта потребуется повторение шагов 2 и 3 для повторного слияния ресурсов xaml, так что вы, вероятно, захотите автоматизировать это путем добавления его в качестве шага или цели сборки.

Пример использования:

Al.exe /out:MyApp.resources.dll /culture:es-ES /embed:MyApp.Form1.es-ES.resources /embed:MyAppWpf.g.es-ES.resources

Дополнительная информация (локализация гибридного приложения) http://msdn.microsoft.com/en-us/library/ms754231.aspx

Чтобы опубликовать метод dustyburwell, работающий в пользовательских элементах управления WPF, встроенных в WinForms, необходимо установить для культуры usercontrol после вызова InitializeComponent() в конструкторе форм WinForms, а затем обновить значения.

  1. Объявить форму WinForms.
  2. Добавьте ElementHost (elementHost1).
  3. Добавьте свой WPF UserControl в elementHost1 (userControl1).
  4. Откройте код формы. Напишите следующий код:
    public Form1()
    {
        InitializeComponent();

        WpfLocalization.LocalizationScope.SetCulture(userControl1, System.Threading.Thread.CurrentThread.CurrentCulture);
        WpfLocalization.LocalizationScope.SetUICulture(userControl1, System.Threading.Thread.CurrentThread.CurrentCulture);
        WpfLocalization.LocalizationManager.UpdateValues();
    }

При каждом изменении CurrentCulture эти 3 строки должны вызываться для каждого пользовательского элемента управления WPF, встроенного в WinForms.

Другие вопросы по тегам