| Китай |
Нестандартные формы и стандартные диалоги
Распределение кода по отдельным файлам
Мы программируем большую задачу по изучению стандартных диалогов и весь код размещаем в двух файлах: StandardDialogs.cs и StandardDialogs.Designer.cs. Для обозримости мы коды для отдельных вкладок упаковали в секции #region. Но у нас осталось еще много диалогов, поэтому для удобства разместим эти секции в отдельных файлах как отдельные части одного класса StandardDialogs.
-
В панели Solution Explorer вызовите для корневого
узла проекта контекстное меню и командой Add/New
Item добавьте
новый пустой файл с именем MessageBox.cs
-
Откройте
файл StandardDialogs.cs в режиме View
Em, выполните
команду меню Edit/Select All и скопируйте все
содержимое в
новый файл MessageBox.cs
-
В файле MessageBox.cs вызовите для рабочей области
контекстное меню и выполните команду Outlining/Collapse
to Definitions,
чтобы свернуть все секции кода
-
Отредактируйте
файл MessageBox.cs так, чтобы в свернутом
состоянии он выглядел следующим образом (убрали базовый класс
Form и ключевое слово public в объявлении класса)
-
В панели Solution Explorer сделайте две
копии теперь уже файла MessageBox.cs и
присвойте им имена OpenFileDialog.cs, SaveFileDialog.cs
-
Щелкните
правой кнопкой мыши на вкладке StandardDialogs.cs редактора
и выполните команду Close All But This, чтобы закрыть все
иные ненужные вкладки
-
Выбирайте
поочередно в файле StandardDialogs.cs свернутые
коды для соответствующих вкладок и перенесите (в
новое скопировать, а в старом убрать) в свои одноименные
файлы как члены частичного класса, открывая файлы в режиме View
Em.
В файле StandardDialogs.cs должен
остаться только код для вкладки "Обзор"
-
В панели Solution
Explorer щелкните правой кнопкой мыши на корневом
узле проекта и командой Add/New Folder добавьте
новую папку с именем ItemsDialogs
-
Удерживая
клавишу Ctrl, выделите файлы MessageBox.cs, OpenFileDialog.cs, SaveFileDialog.cs и
мышью переместите их в новую папку -
Выполните
команду меню Window/Close All Documents, чтобы закрыть все
редактируемые файлы -
Запустите
приложение и убедитесь, что работоспособность его не изменилась,
но код расфасован удобнее
Разработка вкладки ColorDialog
Диалоговое окно ColorDialog порождается классом System.Windows.Forms.ColorDialog. Оно позволяет выбрать цвет, который содержится в свойстве Color типа System.Drawing.Color и может открываться в обычном или расширенном варианте. Несколько других свойств типа Boolean управляют различными настройками диалогового окна ColorDialog. Вот они
| Свойство | Тип | Пояснения |
|---|---|---|
| Color | System.Drawing.Color | Выбранный пользователем цвет |
| AllowFullOpen | bool | При значении true, установленном по умолчанию, окно готово раскрываеться в расширенном варианте с возможностью выбора любых дополнительных цветов |
| AnyColor | bool | Любой цвет |
| FullOpen | bool | Раскрывается в расширенном варианте |
| SolidColorOnly | bool | Только основные цвета |
| ShowHelp | bool | Отобразить кнопку справки |
| CustomColors | int[ ] | Массив дополнительных цветов |
Булевыми значениями этих публичных свойств мы и будем управлять из вкладки ColorDialog.
-
Поместите
на вкладку ColorDialog необходимые элементы
управления и настройте их в соответствии с таблицей
В итоге пользовательский интерфейс вкладки должен выглядеть примерно так
-
Из
панели Toolbox поместите на форму двойным
щелчком компонент ColorDialog и присвойте
ему имя colorDialog
-
Создайте
для кнопки Show обработчик с именем btnShowColorDialog_Click
-
Создайте
для кнопки Reset обработчик с именем btnResetColorDialog_Click
-
Упакуйте
обработчики в секцию #region Вкладка ColorDialog...#endregion
-
Через
панель Solution Explorer создайте в папке ItemsDialogs копию
файла SaveFileDialog.cs и присвойте ей имя ColorDialog.cs
-
Разместите
в файле ColorDialog.cs секцию #region с
заготовками обработчиков btnShowColorDialog_Click и btnResetColorDialog_Click, автоматически
помещенными оболочкой при создании в основную часть класса
в файле StandardDialogs.cs,
и заполните их кодом. Общее содержимое файла ColorDialog.cs должно
быть примерно таким
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
namespace FormsApp
{
partial class StandardDialogs
{
#region Вкладка ColorDialog
// Поле для хранения дополнительных цветов
int[] customColors = new int[16]
{
0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF
};
private void btnShowColorDialog_Click(object sender, EventArgs e)
{
// Создаем совершенно новое диалоговое окно
ColorDialog dlg = new ColorDialog();
// Настраиваем диалоговое окно
dlg.CustomColors = customColors;
foreach (Control ctrl in this.tabPage4.Controls)
{
// Ищем наши флажки на дочерней вкладке
if (ctrl is CheckBox)
{
// Позиционируемся по имени флажка
switch (ctrl.Name.ToString())
{
case "AllowFullOpen":
dlg.AllowFullOpen = ((CheckBox)ctrl).Checked;
break;
case "AnyColor":
dlg.AnyColor = ((CheckBox)ctrl).Checked;
break;
case "FullOpen":
dlg.FullOpen = ((CheckBox)ctrl).Checked;
break;
case "SolidColorOnly":
dlg.SolidColorOnly = ((CheckBox)ctrl).Checked;
break;
case "ShowHelp":
dlg.ShowHelp = ((CheckBox)ctrl).Checked;
break;
}
}
}
// Инициируем предыдущий цвет
dlg.Color = panelColorDialog.BackColor;
// Показываем диалоговое окно и извлекаем
// выбранный пользователем цвет
if (dlg.ShowDialog() == DialogResult.OK)
{
panelColorDialog.BackColor = dlg.Color;
lblColorName.Text = dlg.Color.Name;
// Сохранить выбор дополнительных цветов
customColors = dlg.CustomColors;
}
}
private void btnResetColorDialog_Click(object sender, EventArgs e)
{
// Создаем псевдоним постоянно существующего экземпляра окна
ColorDialog dlg = colorDialog;
// Восстанавливаем окно
dlg.Reset();
// Применяем рефлексию для перебора свойств в цикле
// и передачи их значений флагам интерфейса
PropertyInfo[] props =
typeof(ColorDialog).GetProperties();// Получаем все свойства
// Перебираем свойства
foreach (PropertyInfo prop in props)
{
// Выбираем только логические свойства
if (prop.PropertyType == typeof(bool))
{
// Ищем все элементы-флажки с именем свойства
// У нас только один флажок с уникальным именем
Control[] controls = this.Controls.Find(prop.Name, true);
// Извлекаем значение свойства и присваиваем флажку
((CheckBox)controls[0]).Checked =
(bool)prop.GetGetMethod().Invoke(dlg, null);
}
}
// Восстанавливаем элементы интерфейса
panelColorDialog.BackColor = dlg.Color;
lblColorName.Text = dlg.Color.Name;
}
#endregion
}
}
Листинг
18.24.
Содержимое файла ColorDialog.cs
Свойство CustomColors содержит массив из 16 четырехбайтных целых, в которых содержаться коды дополнительных цветов RGB -модели, представленных в окне 16 плашками. В каждом элементе массива младший байт соответствует цвету Red, затем Green и предпоследний байт - цвету Blue. Последний байт не используется. При создании массива мы сразу инициализировали RGB -байты единицами, что соответствует изначально белому цвету.
Для демонстрации того, что механизм сохранения дополнительных цветов работает, мы специально в обработчике кнопки Show каждый раз создаем диалоговое окно dlg заново и восстанавливаем в нем сохраненные в массиве customColors дополнительные цвета. Постоянное же диалоговое окно colorDialog мы используем только для сброса пользовательского интерфейса.
В обработчике btnResetColorDialog_Click() мы используем механизм отражения ( рефлексию ) для динамического анализа свойств порождающего класса диалогового окна и извлечения их значений из существующего объекта. Для этой цели мы подключили пространство имен System.Reflection. Элементы флажков методом Find() мы ищем во всей форме по их именам, совпадающим с именами свойств, и присваиваем им значения динамически извлеченных свойств. Это сделало программу несколько запутанной, но для большого количества элементов такой подход позволил бы значительно сократить объем кода. Кроме того, таким образом мы знакомимся с разными возможностями языка C#.
-
Запустите
приложение и испытайте работу вкладки ColorDialog
Добавление иконок к формам через файл ресурсов
На простом примере добавления иконок к формам познакомимся с файлами ресурсов оболочки. Этих файлов в проекте может быть сколько угодно и в них на этапе проектирования добавляются элементы, к которым из кода программы можно очень просто обращаться как к обычным свойствам класса (имя класса соответствует имени файла ресурсов). На этапе компиляции эти ресурсы вставляются в код исполнимой сборки и не требуют присутствия самих оригиналов, что улучшает переносимость приложения.
-
В панели Solution Explorer вызовите контекстное меню
для узла проекта и командой Add/New Folder создайте
новую папку с именем Resources
-
Вызовите
контекстное меню для папки Resources и командой Add/New
Item добавьте в нее файл ресурсов с именем Resource1.resx
-
Двойным
щелчком на файле Resource1.resx вызовите
графический редактор ресурсов, раскройте в его верхней части
выпадающий список Add Resource и опцией Add
Existing File добавьте в каталог ресурсов проекта
(и в файл ресурсов) две иконки из прилагаемого
к данной работе каталога Source
-
Установите
в графическом редакторе ресурсов режим представления View
Details и, поочередно выделяя добавленные ресурсы,
через панель Properties присвойте им имена Icon1 и Icon2
-
В панели Solution Explorer выделите файлы формы и
через контекстное меню откройте их в режиме View
Em
-
Добавьте
в конструктор каждой формы после вызова функции InitializeComponent() код
присоединения соответствующей иконки из файла ресурсов,
например, для конструктора Form1() код будет таким
public Form1()
{
InitializeComponent();
this.Icon = Resources.Resource1.Icon1;
}
Листинг
18.25.
Присоединение иконки в конструкторе Form1()
-
Запустите
приложение для каждой формы и убедитесь, что иконки присоединяются
к окну формы, например
-
Перейдите
к следующей части работы (если она уже есть)











