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

Работа с элементами управления (продолжение)

Сохранение настроек приложения. XML-сериализация

При работе с приложением часто возникает необходимость сохранения пользовательских настроек. Одним из способов решения этой задачи является преобразование свойств и полей объекта в специальное представление — формат XML. При этом данные преобразуются в последовательную серию байтов. Этот процесс называется XML-сериализацией. Обратный процесс — восстановление записанной информации — называется десериализацией.

Создайте новое Windows-приложение и назовите его XML-serialization. В качестве свойств для сохранения будем использовать ширину и высоту самой формы.

Подключаем пространство имен для работы с потоками и XML-сериализацией:

using System.IO;
using System.Xml.Serialization;

Создаем новый класс FormSize, в котором объявляем переменные для хранения размеров формы:

public class FormSize
{
  public int height;
  public int width;
}

Размеры формы должны записываться при закрытии формы. В режиме дизайна выделяем форму и в окне Properties переключаемся на события формы (нажимаем на кнопку Events). Создаем обработчик для события Closing формы:

private void Form1_Closing
   (object sender, System.ComponentModel.CancelEventArgs e)
  {
 //Создаем экземпляр frmSize класса FormSize:
 FormSize frmSize = new FormSize();
 // Присваиваем текущие значения высоты и ширины формы 
 //переменным height и width
 frmSize.height = this.Height;
 frmSize.width = this.Width;
 //Cоздаем экземпляр  xmlser класса XmlSerializer
 XmlSerializer xmlser = new XmlSerializer(typeof(FormSize));
 //Создаем переменную filename, которой присваиваем 
 //название файла applicationSettings.xml в текущей директории
 string filename = System.Environment.CurrentDirectory + 
        "\\applicationSettings.xml";
 //Создаем поток filestream для создания XML-файла
 FileStream filestream = new FileStream(filename, FileMode.Create);
 //Создаем сериализацию для экземпляра frmSize
 xmlser.Serialize(filestream, frmSize);
 //Закрываем поток
 filestream.Close();
   
  }

Запускаем приложение. С помощью мыши изменяем размер формы и закрываем ее. В окне Solution Explorer нажимаем на кнопкуICO(Show All Files) — в папке bin/Debug приложения появился файл applicationSettings.xml (рис. 3.20), в котором записаны размеры формы:

<?xml version="1.0"?>
<FormSize xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <height>155</height>
  <width>250</width>
</FormSize>
Файл applicationSettings.xml в окне Solution Explorer

Рис. 3.20. Файл applicationSettings.xml в окне Solution Explorer

Добавим теперь обработчик для события Load формы, в котором данные из applicationSettings.xml будут считываться и применяться для установки размеров:

private void Form1_Load(object sender, System.EventArgs e)
{
  //Создаем экземпляр frmSizeSetup класса FormSize:
  FormSize frmSizeSetup = new FormSize();
  //Cоздаем экземпляр  xmlser класса XmlSerializer
  XmlSerializer xmlser = new XmlSerializer(typeof(FormSize));
  //Создаем переменную filename, которой присваиваем 
  //название файла applicationSettings.xml в текущей директории
  string filename = System.Environment.CurrentDirectory + 
                   "\\applicationSettings.xml";
  //Создаем поток filestream для чтения XML-файла
  FileStream filestream = new FileStream(filename, FileMode.Open);
  //Экземпляру frmSizeSetup передаем данные,
  //полученные в процессе десериализации
  frmSizeSetup = (FormSize)xmlser.Deserialize(filestream);
  //Устанавливаем  текущие высоту и ширину формы
  this.Height = frmSizeSetup.height;
  this.Width = frmSizeSetup.width;
  //Закрываем поток
  filestream.Close();
}

В результате получаем следующее — запускаем приложение, изменяем размер формы, закрываем ее. Снова запускаем приложение — форма имеет установленный размер.

На диске, прилагаемом к книге, вы найдете приложение XML-serialization (Code\Glava3\XML-serialization).

Сохранение настроек приложения в реестре операционной системы

Реестр — это база данных, содержащая конфигурационные сведения операционной системы. Основным средством просмотра и редактирования реестра служит специализированная утилита "Редактор реестра". Для ее запуска открываем окно "Выполнить" (Пуск —> Выполнить или используем сочетание клавиш Windows+R) и набираем regedit. Запустившийся редактор содержит шесть корневых разделов (ветвей), краткое описание которых приводится в таблице 3.3.

Таблица 3.3. Основные разделы реестра операционной системы Windows
Разделы Описание
HKEY_CLASSES_ROOT Содержится информация о зарегистрированных в Windows типах файлов (что и позволяет открывать их по двойному щелчку), классах и их свойствах
HKEY_CURRENT_USER Содержатся настройки оболочки пользователя (например, Рабочего стола, меню "Пуск" и др.). Если на компьютере работает один пользователь и используется обычный вход в Windows, то значения раздела берутся из подраздела HKEY_USERS\.DEFAULT
HKEY_LOCAL_MACHINE Содержится информация, относящаяся к компьютеру: драйверы, установленное программное обеспечение и его настройки
HKEY_USERS Содержит настройки оболочки Windows для всех пользователей. Именно из этого раздела информация копируется в раздел HKEY_CURRENT_USER. Все изменения в HKCU (сокращенное название раздела HKEY_CURRENT_USER) автоматически переносятся в HKU
HKEY_CURRENT_CONFIG Cодержится информация о конфигурации устройств Plug&Play и сведения о конфигурации компьютера с переменным составом аппаратных средств
HKEY_DYN_DATA Содержатся динамические данные о состоянии различных устройств, установленных на компьютере пользователя

Конечным элементом дерева реестра являются ключи или параметры, среди которых можно выделить три основных типа:

  • строковые (например, "C:\Program Files");
  • двоичные (например. 06 31 B2 8C). Максимальная длина такого ключа 16Кб;
  • тип DWORD. Этот тип ключа занимает 4 байта и отображается в шестнадцатеричном и в десятичном виде (например, 0x00000001 (1) — в скобках указано десятичное значение ключа).

Основным классом для работы с реестром (создание новых ключей, их удаление и изменение) в библиотеке .NET Framework является RegistryKey. Описание некоторых методов этого класса приводится в таблице 3.4.

Таблица 3.4. Некоторые методы класса RegistryKey
Метод Описание
CreateSubKey Создание нового параметра реестра или открытие существующего. Название не чувствительно к регистру
DeleteSubKey Удаление существующего параметра
DeleteSubKeyTree Удаление существующего раздела и вложенных подразделов
DeleteValue Удаление значения существующего параметра
OpenSubKey Получение значения парметра только для чтения
SetValue Установка значения
GetValue Получение значения параметра
Close Закрывание параметра и запись его содержимого на постоянной основе

Вернемся к сохранению настроек приложения — теперь для записи размеров формы мы будем создавать и использовать ключи реестра. Создайте новое Windows-приложение и назовите его RegistrySettings. Подключаем пространство имен для работы с классом RegistryKey:

using Microsoft.Win32;

Снова создаем класс FormSize:

public class FormSize
{
  public int height;
  public int width;
}

В обработчике события Closing формы создаем раздел реестра RegApplication, в котором будут храниться данные:

private void Form1_Closing(object sender, 
   System.ComponentModel.CancelEventArgs e)
{
  FormSize frmSize = new FormSize();
  frmSize.height = this.Height;
  frmSize.width = this.Width;
  //Открываем раздел RegApplication
  RegistryKey regkey = Registry.CurrentUser.OpenSubKey
("SOFTWARE\\Microsoft\\RegApplication", true);
  //Если раздел не обнаружен, создаем его
  if (regkey ==null)
  {
 RegistryKey newregkey = Registry.CurrentUser.OpenSubKey
    ("SOFTWARE\\Microsoft", true);
 regkey = newregkey.CreateSubKey("RegApplication");
  }
  //Записываем значения ширины и высоты формы в ключи Height и Width
  regkey.SetValue("Height", frmSize.height);
  regkey.SetValue("Width", frmSize.width);
}

Запускаем приложение, изменяем размер, закрываем его и добавляем обработчик для события Load формы:

private void Form1_Load(object sender, System.EventArgs e)
{
  FormSize frmSizeSetup = new FormSize();
  //Открываем раздел реестра
  RegistryKey regkey = Registry.CurrentUser.OpenSubKey
("SOFTWARE\\Microsoft\\RegApplication");
  //Получаем значения ключей Height и Width
 if (regkey!=null)
  {
  frmSizeSetup.height = Convert.ToInt32(regkey.GetValue("Height"));
  frmSizeSetup.width = Convert.ToInt32(regkey.GetValue("Width"));
  //Устанавливаем текущие значения ширины и высоты формы
  this.Height = frmSizeSetup.height;
  this.Width = frmSizeSetup.width;
  }
}

При перезапуске приложения его измененный размер сохраняется. В реестре появился раздел RegApplication, в котором и находятся два ключа Height и Width со значениями размеров формы в пикселях (рис. 3.21):

Раздел RegApplication  с двоичными  ключами Height и Width

увеличить изображение
Рис. 3.21. Раздел RegApplication с двоичными ключами Height и Width

На диске, прилагаемом к книге, вы найдете приложение RegistrySettings (Code\Glava3\ RegistrySettings).

Почтовая программа Ballet

До сих пор мы рассматривали небольшие программки, которые создавали сами. Теперь мы приступим к рассмотрению блоков достаточно большой программы – почтового клиента Ballet. Исходный код содержит подробные комментарии, и вы можете воспроизвести весь проект заново. Он находится на диске, прилагаемом к книге (Code\Glava3\Mail). Возможно, некоторые вопросы покажутся вам незнакомыми; после прочтения всей книги вы сможете вернуться к ним заново — тогда многое станет понятным. Подобно большинству почтовых клиентов, программа Ballet позволяет отправлять, получать, управлять почтовыми сообщениями и вложениями (рис. 3.22 и рис. 3.23). Поддерживается работа нескольких независимых пользователей и почтовых ящиков.

Написание письма в программе Ballet

увеличить изображение
Рис. 3.22. Написание письма в программе Ballet
Форма для получения списка в почтовом ящике

увеличить изображение
Рис. 3.23. Форма для получения списка в почтовом ящике

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

Добавление проектов

При создании большой программы лучше всего работать над ее частями отдельно, помещая их в проекты. В папке Mail (Code\Glava3\Mail) содержатся три проекта в папках Mail 2003, SendMail и MailApplication. В папке Mail2003 содержится код для приема почтовых сообщений, в папке SendMail — код для его отправки, а в папке MailApplication находится интерфейс программы и добавлены проекты Mail из папки Mail 2003 и SendMail из одноименной папки. В терминах Visual Studio .NET любой создаваемый проект представляет собой часть разработки (решения) Solution (рис. 3.22).

Разработка (решение) Solution в окне Solution Explorer

Рис. 3.22. Разработка (решение) Solution в окне Solution Explorer

При открывании ранее сохраненного проекта мы открывали именно файл NameApplication.sln, представляющий собой решение. Для добавления проектов в решение щелкаем правой кнопкой на его названии и в появившемся меню выбираем Add/New Project (новый проект) или Existing Project (существующий проект) в зависимости от того, что нам нужно (рис. 3.23):

Добавление проектов Mail и SendMail  в разработку MailApplication

увеличить изображение
Рис. 3.23. Добавление проектов Mail и SendMail в разработку MailApplication

Обратите внимание на то, что само решение MailApplication содержит проект MailApplication. Проекты, объединенные в рамках одного решения, являются связанными, а не внедренными. В этом нетрудно убедиться, переименовав папку одного из проектов или внеся изменения в код: в первом случае в результирующем решении будет ошибка, во втором – изменения затронут листинги и в решении.

Елена Дьяконова
Елена Дьяконова

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

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

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

Затем:

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

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

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

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