Нестандартные формы и стандартные диалоги
Разработка вкладки "Обзор"
На этой вкладке мы разместим радиокнопки, при нажатии на которых будет появляться соответствующее стандартное диалоговое окно с минимальными настройками, определенными в коде при его создании.
- В режиме View Designer выделите вкладку " Обзор " и поместите на нее компонент GroupBox как контейнер для красоты оформления. Настройте его так
Свойство | Значение |
---|---|
Name | groupReview |
Dock | Fill |
Text | Пусто |
- Выделив компонент groupReview, поместите внутрь этого контейнера две текстовых метки Label и 10 радиокнопок (элемент RadioButton ). Выровняйте их и настройте как показано на снимке
- Для текстовой метки с белым фоном установите такие свойства
Радиокнопки согласованно работают только тогда, когда они помещены в контейнер. Это может быть форма Form, элемент GroupBox или элемент Panel. Если требуется создать несколько отдельных групп радиокнопок, то их нужно скомпоновать по отдельным контейнерам. Элемент Panel для этих целей хорош тем, что его границы могут быть невидимыми. Любой контейнер является родителем для размещенных в нем элементов. Изменяя свойства контейнера (перемещение, видимость, цвет, стиль), можно управлять аналогичными свойствами всей группы дочерних элементов.
Теперь необходимо запрограммировать эту вкладку. Для всех радиокнопок мы создадим общий обработчик события Click, в котором будем анализировать, какая радиокнопка нажата, чтобы вызвать соответствующий диалог.
- Предварительно замкните интерфейс, выполнив групповую команду Format/Lock Controls
- Выделите все радиокнопки вкладки, обведя их курсором. В панели Properties создайте общий для всех радиокнопок обработчик для события Click двойным щелчком на поле этого события
- Опять выделите все радиокнопки и в панели Properties скорректируйте имя обработчика события Click, сгенерированное автоматически, на свое - standardDialogs_Click
Оболочка с обработчиками работает так: если тело обработчика пустое и нет иных подключений, то он переименовывается, если непустое или есть на него ссылки иных элементов, то создается пустой обработчик с новым именем.
В теле обработчика воспользуемся тем фактом, что значение свойства Text всех радиокнопок мы задали по имени соответствующего диалога, кроме последнего, который разработаем позднее. При каждом срабатывании события Click мы по свойству Text радиокнопки определим, какой диалог создать и вывести на экран.
- Заполните обработчик standardDialogs_Click() следующим кодом
#region Вкладка "Обзор" private void standardDialogs_Click(object sender, System.EventArgs e) { RadioButton radio = (RadioButton)sender; // Для контроля при отладке System.Diagnostics.Debug.WriteLine("Нажата радиокнопка " + radio.Text); switch (radio.Text.Trim())// Чтобы убрать возможные пробелы { case "MessageBox": MessageBox.Show( // Статический метод - модальный вызов "Это удобная форма выдачи сообщений!", // Сообщение "Стандартный диалог MessageBox", // Заголовок окна MessageBoxButtons.OK, // Кнопка OK MessageBoxIcon.Stop);// Критическая иконка break; case "OpenFileDialog": OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Title = "OpenFileDialog"; openFileDialog.ShowDialog();// Модальный вызов openFileDialog.Dispose();// Вызов сборщика мусора break; case "SaveFileDialog": SaveFileDialog saveFileDialog = new SaveFileDialog(); saveFileDialog.Title = "SaveFileDialog"; saveFileDialog.ShowDialog();// Модальный вызов saveFileDialog.Dispose();// Вызов сборщика мусора break; case "ColorDialog": ColorDialog colorDialog = new ColorDialog(); colorDialog.ShowDialog();// Модальный вызов colorDialog.Dispose();// Вызов сборщика мусора break; case "FontDialog": FontDialog fontDialog = new FontDialog(); fontDialog.ShowDialog();// Модальный вызов fontDialog.Dispose();// Вызов сборщика мусора break; case "PrintDialog": PrintDialog printDialog = new PrintDialog(); printDialog.AllowSomePages = true;// Настраиваем доступ к выбору страниц printDialog.ShowHelp = true; // Отображать кнопку помощи printDialog.Document = new System.Drawing.Printing.PrintDocument(); DialogResult result = printDialog.ShowDialog();// Модальный вызов if (result == DialogResult.OK) MessageBox.Show("Пользователь хотел печатать"); printDialog.Dispose();// Вызов сборщика мусора break; case "PrintPreviewDialog": PrintPreviewDialog printPreviewDialog = new PrintPreviewDialog(); printPreviewDialog.Document = new System.Drawing.Printing.PrintDocument(); printPreviewDialog.ShowDialog();// Модальный вызов printPreviewDialog.Dispose();// Вызов сборщика мусора break; case "PageSetupDialog": PageSetupDialog pageSetupDialog = new PageSetupDialog(); pageSetupDialog.PageSettings = new System.Drawing.Printing.PageSettings(); pageSetupDialog.PrinterSettings = new System.Drawing.Printing.PrinterSettings(); //Не показывать сеть в диалоге принтера pageSetupDialog.ShowNetwork = false; pageSetupDialog.ShowDialog();// Модальный вызов pageSetupDialog.Dispose();// Вызов сборщика мусора break; case "FolderBrowserDialog": FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog(); folderBrowserDialog.Description = "Установите нужный каталог текущим"; // Каталог по умолчанию - "Мои документы" folderBrowserDialog.RootFolder = Environment.SpecialFolder.Personal; folderBrowserDialog.ShowDialog();// Модальный вызов folderBrowserDialog.Dispose();// Вызов сборщика мусора break; default: MessageBox.Show("Пока нет - создадим позднее", "Самодельный диалог", MessageBoxButtons.OK, MessageBoxIcon.Stop); break; } } #endregionЛистинг 18.12. Код обработчика нажатия радиокнопок вкладки "Обзор"
Здесь мы применили операторы #region... #endregion, чтобы для удобства редактирования разместить код, относящийся к каждой вкладке, в отдельные секции.
- Запустите приложение и испытайте вкладку "Обзор" . Должны вызываться окна всех упомянутых диалогов, например, ColorDialog
Заметьте, что все диалоги мы создаем и вызываем через код, хотя каждый из них имеет визуальный аналог во вкладке Toolbox. Здесь всю работу графических возможностей среды разработки мы сделали вручную. Это не всегда лучший вариант для быстрой разработки интерфейса, но всегда нужно понимать, что делает оболочка с кодом, чтобы в любой момент можно было вмешаться и подправить код более тонко. Аналогичная ситуация при работе с Web -редакторами: основную работу можно автоматизировать через графическую среду, но может возникнуть необходимость вмешиваться в генерируемый ею HTML -код.