Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Создание мультиязычного интерфейса.

Практическая работа

Сначала нужно настроить нашу форму для возможности поддержки многоязычности.
Установите в свойствах формы параметр: Localizable - true

Обратите внимание, что свойство Language установлено в значение по умолючанию на данный момент. Мы его изменим немного дальше. Когда форма поддерживает локализацию, при изменении свойства Language можно устанавливать различные языки/культуры при которых содержимое формы будет применяться только для этого языка. Тем не менее, нельзя создавать форму сразу с установленным каким-либо языком.

Важно! Нужно создавать форму и все ее элементы с установкой Language по умолчанию.

Сама идея локализации предусматривает то, что ваше приложение работает одинаково и его логика не меняется для различных языков. Поэтому саму форму мы создаём в языке по умолчанию. Когда форма готова - приступаем к локализации.

Установив свойство Language в необходимый нам язык мы меняем текстовые свойства на нашей форме на необходимый язык вручную. Т.е. локализируем нашу форму и делаем ее такой, какой она будет выглядеть для пользователя, использующего выбранный язык в программе. Выше отображена форма с установленным английским языком, применяемым в США (забегая вперед, это может быть выражено в классе CultureInfo("en-US").

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

После того как были добавлены эти 2 языковых варианта реализации одной формы можно открыть Обозреватель решений и увидеть:

Как видно на картинке, Visual Studio создает для нас по новому файлу ресурсов для каждой локализации, которую мы добавляем для приложения. Если мы откроем какую-то из локализаций - мы увидим следующее:

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

Установить компонент, который обеспечит переключение между настроенными локализациями. Простейший пример кода при изменении значения в СomboBox.

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)

{

if (comboBox1.Text == "EN") ChangeFormLanguage("en-US");

else ChangeFormLanguage("ru-RU");

}

private void ChangeFormLanguage(string newLanguageString)

{

var resources = new ComponentResourceManager(typeof(Form1));

CultureInfo newCultureInfo = new CultureInfo(newLanguageString);

//Применяем для каждого контрола на форме новую культуру

foreach (Control c in this.Controls)

{

resources.ApplyResources(c, c.Name, newCultureInfo);

}

//Отдельно меняем для тайтла самой формы локализацию

resources.ApplyResources(this, "$this", newCultureInfo);

}

Рассмотрим вопрос о централизованном хранении настроек локализации для всего приложения с реализацией интерфейса, который позволит менять языковые настройки для форм приложения.

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

Первым делом организуем Enum, который будет определять элементы перечисления, которыми мы будем пользоваться в программе, оперируя установками текущей культуры/локализации.

Обычно для реализации интерфейсов, классов и энумов в проектах C# реализуем отдельные папки для хранения блоков кода программы данных типов:

AvialableLocalizations выглядит следующим образом:

public enum AvaliableLocalizations
{
[Description("en-US")]
English,
[Description("ru-RU")]
Russian

}

Внимание! Особая роль отводится атрибутам Description. В текстовых атрибутах должны быть заданы подходящие атрибуты, которые служили бы затем корректным параметром для конструктора CultureInfo.

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

Реализуем интерфейс ILanguageChangable со следующим содержимым:

namespace Active_Directory_Worker.Interfaces
{
interfaceILanguageChangable
{
void ChangeFormLanguage(Enums.AvaliableLocalizations newLocalization);
}
}

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

Соответственно, определения форм, которые могут изменять локализацтю будут подобны нашей основной форме:

public partial classStartWindow:Form, ILanguageChangable

Теперь снова вернемся к нашему Enum-у. Каждому элементу, который обозначает какой-то из языков локализации, соответствует Description со значением, которое мы потом используем в конструкторе CultureInfo. Однако, с помощью стандартных методов извлечь Description нельзя, поэтому для извлечения описаний используем следующий класс:

public static class EnumDescriptionHelper
{
public static string GetEnumDescription(Enum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());

DescriptionAttribute[] attributes =
(DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);

if (attributes!= null && attributes.Length > 0)
return attributes[0].Description;
else
return value.ToString();
}
}

По-сути, код выше организовывает общий механизм, облегчающий и упрощающий работу с локализациями, позволяя их гибко добавлять/удалять/изменять.

Теперь задействуем этот механизм.

Для централизованного управления механизмом локализации во всей программе проще всего объявить или статический класс настроек или класс, реализующий паттерн Singleton (что более обоснованно с точки зрения архитектуры программы). В этом файле реализуем функцию, которая будет доступна из любого места в программе:

public static class Settings
{
public AvaliableLocalizations CurrentLocalization;

internal CultureInfo GetCulture()
{
return new CultureInfo(EnumDescriptionHelper.GetEnumDescription(CurrentLocalization));
}

internal void SetCulture(AvaliableLocalizations newLocalization)
{
CurrentLocalization = newLocalization;
Thread.CurrentThread.CurrentUICulture =
new CultureInfo(EnumDescriptionHelper.GetEnumDescription(CurrentLocalization));
}
}

Теперь рассмотрим реализацию интерфейса в файле кода нашего окна:

public void ChangeFormLanguage(AvaliableLocalizations newLocalization)
{
_settings.SetCulture(newLocalization);

var resources = new ComponentResourceManager(typeof(StartWindow));

CultureInfo newCultureInfo = new CultureInfo(EnumDescriptionHelper.GetEnumDescription(newLocalization));

foreach (Control c in this.Controls)
{
resources.ApplyResources(c, c.Name, newCultureInfo);
}

resources.ApplyResources(this, "$this", newCultureInfo);
//
}

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


private void TSMI_English_Click(object sender, EventArgs e)
{
ChangeFormLanguage(AvaliableLocalizations.English);
}

private void TSMI_Russian_Click(object sender, EventArgs e)
{
ChangeFormLanguage(AvaliableLocalizations.Russian);
}

 

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...