Как запустить интернационализированный WPF-проект в SharpDevelop 4.2?

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

Для начала я хочу узнать, как справиться с интернационализацией, поскольку я никогда раньше этого не делал.

В качестве IDE я использую SharpDevelop или #develop, но вы бы написали это по буквам. Я хочу использовать C # и WPF, так как сейчас я изучаю XAML / WPF.

Итак, я создаю новый WPF-проект в ShardDevelop. В главном окне я создаю ComboBox и TextBlock.

ComboBox получает две записи: «немецкий» и «английский». Текстовый блок должен показывать "Hallo Welt!" или «Hello World!» в зависимости от выбранного языка.

Теперь наступает момент, когда я застреваю. Я предполагаю, что каждый язык получает отдельный файл в стиле XML / XAML (имеет смысл). Где находятся эти файлы и как они и их содержимое загружаются, чтобы загружался текст выбранного языка?

Я нашел несколько примеров, но все они связаны с созданием Resource-DLL и использованием какой-то странной программы для их декомпиляции обратно в файл csv ... я не понимаю, разве нет более простого способа?


Я сделал следующий шаг. Текст TextBlock теперь загружается через "{StaticResource Strings.MainForm.hwText}". Теперь это выглядит так:

<TextBlock Text="{StaticResource Strings.MainForm.hwText}" />

Также я создал один ResourceDictionary для немецкого языка и один для английского, которые определяют ключ, который я использовал в TextBlock.

В Application.Resources Part я загружаю один из ResourceDictionary по умолчанию.

Теперь проблема заключается в следующем: как я могу «выгрузить» этот словарь во время выполнения и заменить его другим?

Конечно, я использую событие SelectionChange ComboBox, но что мне там делать?


Задача решена!! Благодаря kmatyaszek

Хотя я немного изменил код обработчика событий в соответствии со своими потребностями:

Uri baseUri = new Uri(AppDomain.CurrentDomain.BaseDirectory);
Uri uri = new Uri(baseUri,"Languages\\lang."+((sender as ComboBox).SelectedItem as ComboBoxItem).Tag.ToString()+".xaml");
if(File.Exists(uri.LocalPath) || File.Exists((uri = new Uri(baseUri,"Languages\\lang.de-DE.xaml")).LocalPath)){
    ResourceDictionary dict = new ResourceDictionary();
    dict.Source = uri;
    this.Resources.MergedDictionaries.Add(dict);
}

person Martin Weber    schedule 17.12.2012    source источник
comment
Я не знаю насчет SharpDevelop, но в VS вы можете очень легко создавать файлы .resx. В окне свойств вы можете установить локализацию. Может быть, у SharpDevelop есть что-то подобное.   -  person The_Cthulhu_Kid    schedule 17.12.2012
comment
спасибо за совет, я разберусь с этим! :)   -  person Martin Weber    schedule 17.12.2012
comment
Если найдете, дайте мне знать :)   -  person The_Cthulhu_Kid    schedule 17.12.2012


Ответы (1)


Если вы создали два файла ResourceDictionary, вы можете привязать их с помощью DynamicResource.

Пример:

Первый файл ресурсов (Lang.en-US.xaml):

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:system="clr-namespace:System;assembly=mscorlib">

    <system:String x:Key="Username">Username:</system:String>
    <system:String x:Key="Password">Password:</system:String>
    <system:String x:Key="close">Close</system:String>
    <system:String x:Key="login">Login</system:String>        
</ResourceDictionary>

Второй файл ресурсов (Lang.pl-PL.xaml):

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:system="clr-namespace:System;assembly=mscorlib">

    <system:String x:Key="Username">Login:</system:String>
    <system:String x:Key="Password">Hasło:</system:String>
    <system:String x:Key="close">Zamknij</system:String>
    <system:String x:Key="login">Zaloguj</system:String>
</ResourceDictionary>

Установите язык по умолчанию в ресурсах приложения:

 <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Lang.en-US.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
 </Application.Resources>

Допустим, у нас есть ComboBox, как показано ниже:

<ComboBox Name="cbLang" Margin="2" SelectionChanged="cbLang_SelectionChanged" >
                <ComboBoxItem Content="English" Tag="en-US" />
                <ComboBoxItem Content="Polish" Tag="pl-PL" />
  </ComboBox>

Выделение кода программной части изменено:

 private void cbLang_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            ResourceDictionary dict = new ResourceDictionary();

            switch (((sender as ComboBox).SelectedItem as ComboBoxItem).Tag.ToString())
            {
                case "en-US":
                    dict.Source = new Uri("Lang.en-US.xaml", UriKind.Relative);
                    break;
                case "pl-PL":
                    dict.Source = new Uri("Lang.pl-PL.xaml", UriKind.Relative);
                    break;
                default:
                    break;
            }
            this.Resources.MergedDictionaries.Add(dict);
        }

А привязать можно так:

 <TextBlock Text="{DynamicResource Username}" VerticalAlignment="Center" />
person kmatyaszek    schedule 17.12.2012
comment
Я что-то не так понял? (String)Application.Current.FindResource("Username") всегда получает значение по умолчанию, установленное в <Application.Resources> (в вашем случае имя пользователя). Любой совет? - person Boern; 27.06.2014
comment
@Ben не могли бы вы подготовить пример решения и загрузить, например, в скайдрайв? - person kmatyaszek; 16.07.2014