|
При нажатии на Сумма в примере ArbitraryMethod из Лекция 7, VS 2013 выдается ошибка: Необработанное исключение типа "System.InvalidOperationException" в System.Windows.Forms.dll Дополнительные сведения: Недопустимая операция в нескольких потоках: попытка доступа к элементу управления "lblResult" не из того потока, в котором он был создан. Затем: Необработанное исключение типа "System.InvalidOperationException" в mscorlib.dll Дополнительные сведения: Для каждой асинхронной операции метод EndInvoke может вызываться только один раз. |
Справочные материалы. перевод приложений. специальные возможности
Пользовательский выбор языка. Перевод сообщений приложения
В рассмотренном примере меняется пользовательский интерфейс, представляющий собой значения свойства 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):
Устанавливаем свойству 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).
Проделаем эту операцию еще раз, новый шаблон назовем ClosingText.ru-RU.resx. Мы добавили эти файлы для хранения в них текстовых переменных, используемых приложением для различных локализаций. Откроем ресурс ClosingText.en-US.resx и введем переменную MessageText, в значении value которой укажем текст Do you want to save changes in this document?, выводимый приложением при закрытии (рис. 8.29).
Аналогично, в ресурсе ClosingText.ru-RU.resx создадим такую же переменную, в значении которой укажем текст на русском языке: "Вы хотите сохранить изменения в документе?" (рис. 8.30).
Переходим в код формы, подключаем следующие пространства имен:
//Пространство имен, используемое для определения культуры //приложения и операционной системы 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;




