Опубликован: 11.09.2006 | Уровень: специалист | Доступ: платный
Лекция 8:

Справочные материалы. перевод приложений. специальные возможности

Пользовательский выбор языка. Перевод сообщений приложения

В рассмотренном примере меняется пользовательский интерфейс, представляющий собой значения свойства Text элементов управления. Между тем в приложениях используются текстовые сообщения, определяемые в коде, например, в "Работа с элементами управления" в приложении Notepad C# при попытке закрыть измененный документ появлялось окно-предупреждение Do you want save changes in NameDocument?. Рассмотрим перевод сообщений приложения и пользовательское изменение интерфейса. Скопируем проект TextEditor из "Работа с элементами управления" . В классе формы добавляем переменные для сохранения документа:

public bool IsSaved = false;
public string fileName;

Создаем метод Save, в который вставляем вырезанный обработчик пункта меню mnuSave:

public void Save(object sender, System.EventArgs e)
  {
    //Показываем диалог выбора файла
    saveFileDialog1.ShowDialog();
    // В качестве имени сохраняемого файла устанавливаем переменную fileName
     fileName=saveFileDialog1.FileName;
    //Создаем поток fs и открываем файл для записи.
    FileStream filestream = File.Open(fileName, FileMode.Create, FileAccess.Write);
    //Проверяем,  открыт ли поток,  и если открыт, выполняем условие
    if(filestream != null)
    {
      //Создаем объект streamwriter и связываем его с потоком filestream
      StreamWriter streamwriter = new StreamWriter(filestream);
      //Записываем данные из TextBox в файл
      streamwriter.Write(txtBox.Text);
      //Переносим данные из потока в файл
      streamwriter.Flush();
      //Закрываем поток
      filestream.Close();
      IsSaved = true;
    }
  }
Листинг 8.1.

В обработчике меню mnuSave вызываем этот метод:

private void mnuSave_Click(object sender, System.EventArgs e)
  {
    this.Save( fileName, e);
  }

Добавляем обработчик события Closing формы:

private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
  {
    //Если переменная IsSaved имеет значение true, т. е. документ новый документ 
  //был сохранен (Save As) или в открытом документе были сохранены изменения (Save), 
  то выполняется условие
    if(IsSaved ==true)
      //Появляется диалоговое окно, предлагающее сохранить документ.
      if  (MessageBox.Show("Do you want to save changes in this document?", 
        "Message", MessageBoxButtons.YesNo, 
        MessageBoxIcon.Question) == DialogResult.Yes)
        //Если была нажата  кнопка Yes, вызываем метод Save
      {
        this.Save( fileName, e);
      }  
  }
Листинг 8.2.

Запускаем приложение. Теперь при попытке закрыть измененный документ появляется окно-предупреждение. Закрываем приложение, переключаемся в режим дизайна и добавляем следующие пункты меню (рис. 8.27):

Name Text
mnuLanguage &Language
mnuEnglish &English
mnuRussian &Русский
Пункт главного меню Language

Рис. 8.27. Пункт главного меню Language

Устанавливаем свойству Localizable формы значение True, в свойстве Language выбираем язык English (United States). Компилируем приложение, в свойстве Language выбираем язык Russian (Russia). Переводим пункты меню на русский язык:

Name Text
mnuFile &Файл
mnuOpen &Открыть
mnuSave &Сохранить
mnuLanguage &Язык
mnuEnglish &English
mnuRussian &Русский

В окне Solution Explorer щелкаем правой кнопкой на названии проекта TextEditor и добавляем новый файлAdd/Add New Item… . В появившемся окне выбираем шаблон Assembly Resource File и называем его ClosingText.en-US.resx (рис. 8.28).

 Файл Assembly Resource File

Рис. 8.28. Файл Assembly Resource File

Проделаем эту операцию еще раз, новый шаблон назовем ClosingText.ru-RU.resx. Мы добавили эти файлы для хранения в них текстовых переменных, используемых приложением для различных локализаций. Откроем ресурс ClosingText.en-US.resx и введем переменную MessageText, в значении value которой укажем текст Do you want to save changes in this document?, выводимый приложением при закрытии (рис. 8.29).

Переменная MessageText в ресурсе ClosingText.en-US.resx

Рис. 8.29. Переменная MessageText в ресурсе ClosingText.en-US.resx

Аналогично, в ресурсе ClosingText.ru-RU.resx создадим такую же переменную, в значении которой укажем текст на русском языке: "Вы хотите сохранить изменения в документе?" (рис. 8.30).

Переменная MessageText в ресурсе ClosingText.ru-RU.resx

Рис. 8.30. Переменная MessageText в ресурсе ClosingText.ru-RU.resx

Переходим в код формы, подключаем следующие пространства имен:

//Пространство имен, используемое для определения культуры
//приложения и операционной системы
using System.Globalization;
//Пространство, используемое для работы с файлами ресурсов .resx,
//такими как ClosingText.en-US.resx, ClosingText.ru-RU.resx.
using System.Resources;
//Пространство для работы со сборками, более подробно о них см. лекцию 9.
using System.Reflection;
using System.Threading;

В классе формы объявляем следующие переменные и объекты:

//Переменная выбора, необходимая для определения культуры 
public string CultureDefine;
//Переменная для хранения английской культуры
private  string EnglishCulture;
//Переменная для русской культуры.
private  string RussianCulture;

Для управления ресурсами используется класс ResourceManager, который позволяет извлекать значения переменных, созданных в файле-ресурсе. Общая схема использования этого класса:

ResourceManager resourceManager = new  ResourceManager
("ПространствоИмен.НазваниеРесурса", Assembly.GetExecutingAssembly());

Для использования извлекаемой строковой переменной обращаемся к ее имени в ресурсе:

MessageBox.Show(resourceManager.GetString("ИмяПеременнойвРесурсе");

Возвращаемся к нашему листингу:

//Создаем экземпляр resourceManager класса ResourceManager
 ResourceManager resourceManager;
Елена Дьяконова
Елена Дьяконова

При нажатии на Сумма в примере ArbitraryMethod из Лекция 7, VS 2013 выдается ошибка: 

Необработанное исключение типа "System.InvalidOperationException" в System.Windows.Forms.dll

Дополнительные сведения: Недопустимая операция в нескольких потоках: попытка доступа к элементу управления "lblResult" не из того потока, в котором он был создан.

Затем:

Необработанное исключение типа "System.InvalidOperationException" в mscorlib.dll

Дополнительные сведения: Для каждой асинхронной операции метод EndInvoke может вызываться только один раз.

Александр Сороколет
Александр Сороколет

Свойство WindowState формы blank Maximized. Не открывается почемуто на всё окно, а вот если последующую форму бланк открыть уже на макс открывается :-/

Иван Циферблат
Иван Циферблат
Россия, Таганрог, 36, 2000