Лекция № 4
Тема: «Меню, панели инструментов, диалоги»
План
1. Многострочное окно редактирования
2. Работа с меню
3. Панели инструментов и строка статуса
4. Системные диалоги
5. Форма регистрации и форма-заставка
1. Многострочное окно редактирования
Рассмотренный ранее компонент TextBox может работать в режиме многострочного текстового поля, то есть текст, который не помещается на стоке будет автоматически переноситься на новую строку, а по клавише Enter можно перейти на новый абзац. Такое поле имеет те же свойства, что и обычный TextBox, но использует и ряд новых:
|
Свойство |
Описание |
|
Lines |
Коллекция строк в поле. Так как поле многострочное, то каждая строка - это элемент коллекции Lines. Обратиться к нужной строке можно с помощью записи Lines[i]. |
|
Lines.Length |
Число строк в многострочном поле (размер массива Length) |
|
Multiline |
Включает для поля режим "многострочности" |
|
ScrollBars |
Управляет отображением полос прокрутки в поле: вертикальная, горизонтальная, обе или ни одной. Данное свойство не рекомендуется активировать в режиме конструктора, так как полоса будет отображаться всегда, даже если она не имеет смысла и содержимое поля помещается в нем. Целесообразнее данное свойство активировать программно по мере заполнения поля текстом (см. ниже). |
|
WordWrap |
Активирует режим автоматического переноса текста на новую строку. |
С многострочным компонентом TextBox можно выполнять те же действия, что и над обычным полем. Для этого используют ряд методов:
textBox1.AppendText("текст"); //добавляет указанный текст в конец поля. Если после добавления текст курсор нужно перевести на новую строку, то к тексту добавляют константу Environment.NewLine (см. пример ниже)
textBox1.Clear(); //очищает содержимое поля
textBox1.ClearUndo(); //очищает буфер отмены действий. Отменить последнюю операцию будет нельзя
textBox1.Copy(); //копирует выделенный фрагмент из поля в буфер обмена
textBox1.Cut(); //вырезает выделенный фрагмент из поля в буфер обмена
textBox1.Focus(); //передает фокус в поле, устанавливая в него курсор
textBox1.Paste(); //вставляет содержимое буфера обмена в поле
textBox1.ResetText(); //сбрасывает свойство Text в значение по умолчанию. Имеет смысл, если свойство Text по умолчанию не пустое
textBox1.Select(int start, int length); //выделяет в поле фрагмент, начиная с позиции start и длиной в length символов
textBox1.SelectAll(); //выделяет все содержимое поля
textBox1.Undo(); //отменяет в поле последнее выполненное действие
Пусть, например, в вашем приложении есть поле textBox1, в котором пользователь вводит имя сотрудника, и есть кнопка, при нажатии на которую в многострочное поле textBox2 должна занестись шапка характеристики этого сотрудника, после чего пользователь может заполнить текст характеристики.
Обработчик нажатия на кнопку может иметь вид:
//очищаем многострочное поле
textBox1.Clear();
//добавляем в поле строку и в конце указываем
//константу перехода на следующую строку
textBox1.AppendText("Характеристика"+Environment.NewLine);
textBox1.AppendText("Сотрудник "+textBox1.Text+Environment.NewLine);
//ставим курсор в поле для ввода текста характеристики
textBox1.Focus();
Автовыделение текста в поле
При переводе фокуса в текстовое поле клавишей Tab или вызовом метода Focus() , курсор автоматически становится в конец текста. Если пользователь хочет заменить содержимое поля на новое значение, то он будет вынужден удалить старое значение перед вводом нового. Борее удобным решением было бы, чтобы при переходе в поле весь текст в нем выделялся автоматически. В этом случае пользователю будет достаточно начать вводить новый текст, который заменит старый.
Компонент TextBox не имеет свойства, отвечающего за автоматическое выделение всего текста, поэтому данный функционал придется реализовать с помощью кода. В событии Enter нужного поля (введите команду):
void textBox1_Enter(object sender, EventArgs e)
{
(sender as TextBox).SelectAll();
}
Обратите внимание, что в приведенном коде вместо имени компонента используется универсальная запись (sender as TextBox). Это позволяет использовать данный код для любого текстового поля, не меняя код. А еще проще - в обработчике события Enter нужного поля просто укажите обработчик этого же события для поля textBox1.
Отображение полосы прокрутки в поле
Если у текстового поля включен в многострочный режим, то по мере ввода текста возникает необходимость отображения полос прокрутки (чаще всего - вертикальных). Для этого компонент имеет специальное свойство ScrollBars, которое можно задать в режиме конструктора. Однако, если свойство включено, то даже при пустом поле или небольшом объеме текста в нем, данная полоса будет отображаться, что не совсем логично.
Более целесообразно показывать и скрывать полосу прокрутки в соответствии с текущим состоянием поля: если текс не помещается в поле - полоса появляется, иначе - скрывается. Такой режим работы можно обеспечить с помощью кода. В событии TextChanged поля введите код:
private void textBox1_TextChanged(object sender, EventArgs e)
{
//описываем переменную и присваиваем ей
//размер текста, введенного в textBox2, в точках
Size textBoxRect = TextRenderer.MeasureText(this.textBox1.Text, this.textBox1.Font,
new Size(this.textBox1.Width, int.MaxValue),
TextFormatFlags.WordBreak | TextFormatFlags.TextBoxControl);
//если высота текста больше высоты поля
if (textBoxRect.Height > textBox1.Height)
//отображаем вертикальную полосу прокрутки
this.textBox1.ScrollBars = ScrollBars.Vertical;
//иначе
else
//скрываем полосы прокрутки
this.textBox1.ScrollBars = ScrollBars.None;
}
Многострочное текстовое поле и файлы
Содержимое текстового поля можно сохранить в файл, а содержимое любого файла можно загрузить в текстовое поле. Для этого можно использовать команд вида:
textBox1.Lines = File.ReadAllLines("имя_файла"); //загружает файл в поле textBox1
File.WriteAllLines("имя_файла",textBox1.Lines); //содержимое поля textBox1 сохраняет в файл
Замечание: для работы с классом File подключите пространство имен using System.IO;
Имя файла можно задать как константу в двойных кавычках. При вводе полного имени символ обратного слеша ("\") дублируется. Например:
"e:\\arhiv\\docs\\report.txt"
Чаще всего имя файла задается не в коде, а с помощью специальных диалогов открытия и сохранения файлов. Работу сними мы рассмотрим в этой лекции ниже.
2. Работа с меню
В реальных приложениях пользователь может выполнить большое количество разных действий. Ранее мы вызывали нужные действия с помощью кнопок. Однако, если для каждого действия создавать отдельную кнопку, то то форма будет полностью заполнена кнопками, что сделает работу с программой некомфортной. Более естественным способом является создание на форме строки меню - отдельной панели с перечнем команд, каждая из которых может открыть собственное подменю (список вложенных команд). Такая строка меню чаще всего отображается в верхней части окна, хотя это не обязательно.
При создании меню нужно руководствоваться рядом правил:
- если команда меню открывает новое окно, то название такого меню должно заканчиваться многоточием (///);
- по возможности присваивайте командам меню сочетания клавиш, чтобы продвинутые пользователи могли вызывать нужные им команды быстрее;
- при выборе названий для команд меню используйте привычные названия из других приложений (Вырезать, Копировать, Вставить, Формат и т.п.).
Для создания меню существует два компонента: MenuStrip – главное меню и ContextMenuStrip – контекстное (всплывающее) меню. После добавления этих компонентов, они отображаются на отдельной панели под формой.
Компонент MenuStrip
Компонент может состоять из набора команд, расположенных по горизонтали (разделы меню), и из наборов подменю - списков дополнительных команд, открываемых при щелчке на нужном разделе. При работе с компонентом Вам придется иметь дело со свойствами двух типов: свойствами самого меню и свойствами отдельной команды меню. Чтобы отобразить свойства компонента меню, выделите компонент на панели под формой. Основные свойства компонента:
|
Свойство |
Описание |
|
Name |
Имя компонента для обращения к нему в коде |
|
Dock |
Задает размещение меню на форме. По умолчанию у верхнего края |
|
Items |
Коллекция команд меню. Позволяет создавать и редактировать набор разделов и подменю для каждого раздела |
|
LayoutStyle |
Задает вид расположения разделов меню. По умолчанию - по горизонтали |
|
ShowItemToolTip |
Включает отображение всплывающих подсказок для команд меню |
|
Text |
Задает название для раздела меню. Если перед нужным символом в названии команды указать знак "&", то такой символ станет "горячим", и команду меню можно будет вызвать с помощью сочетания клавиш Alt+символ |
|
TextDirection |
Задает ориентацию написания названий команд меню. По умолчанию - горизонтальная |
Основное свойство - Item, которое открывает окно редактора команд меню вида:

В левой части окна отображаются разделы меню. Можно добавить, удалить и изменить порядок следования разделов с помощью соответствующих кнопок.
В правой части отображаются свойства выделенного раздела. Опишем основные из них:
|
Свойство |
Описание |
|
Name |
Имя компонента для обращения к нему в коде |
|
Alignment |
Выравнивание раздела относительно всей панели меню |
|
AutoToolTip |
Включает автоматическое отображение всплывающей подсказки для команды меню |
|
Checked |
Позволяет отметить команду меню флажком (true) или снять метку (false) |
|
CheckOnClick |
Включает для команды меню работу в виде флажка по клику (вкл/выкл) |
|
DisplayStyle |
Задает стиль отображения названия команды меню. По умолчанию - текст и иконка |
|
DropDownItems |
Открывает новое окно редактора команд меню, в котором можно создать перечень команд подменю для выбранного раздела. Данное окно похоже на рассматриваемое |
|
Enabled |
Включает или выключает признак активности команды меню. Если в каком-то режиме работы программы команда меню не имеет смысла, то ее можно сделать неактивной (будет отображаться серым цветом) |
|
Image |
Задает иконку для отображения возле названия команды меню |
|
ImageAlign |
Задает выравнивание иконки в названии команды меню |
|
ShortcutKeys |
Сочетание клавиш для команды меню |
|
ShowShortcutKeys |
Включает отображение сочетания клавиш для команд меню |
|
Text |
Задает название для команды меню. Если в этом свойстве указать знак тире "-", то команда меню отобразиться как разделитель. Если перед нужным символом в названии команды указать знак "&", то такой символ станет "горячим", и команду меню можно будет вызвать с помощью сочетания клавиш Alt+символ |
|
TextAlign |
Выравнивание текста в команде меню |
|
TextDirection |
Задает ориентацию написания названий команд меню. По умолчанию - горизонтальная |
|
TextImageRelation |
Задает размещение текста и иконки внутри названия команды меню |
|
ToolTipText |
Задает текст всплывающей подсказки |
С помощью свойства DropDownItems можно создать для раздела меню список выпадающих команд (подменю). При этом откроется такое же окно, как показано на рисунке выше, с таким же принципом управления набором команд и такими же свойствами для каждой команды.
Для создания обработчика события для команды меню раскройте нужный раздел меню, найдите нужную команду и выполните на ней двойной щелчок. В результате в коде появится заготовка обработчика события, в которой введите нужный код.
Приведем несколько примеров для работы с меню.
Пусть на форме имеется команда меню Редактирование – Заблокировать под именем Name = ToolStripMenu21, которая работает в виде флажка (включено свойство CheckOnClick) . Если пункт меню отмечен флажком, то поле textBox1 на этой же форме блокируется для редактирования. А если нет, то – доступно.
Для команды меню напишем код:
private void ToolStripMenuItem21_Click(object sender, EventArgs e)
{
textBox1.ReadOnly = ToolStripMenuItem21.Checked;
}
Рассмотрим для этого примера другую ситуацию. Пусть пункт меню отмечается не флажком, а меняется самое название пункта (Заблокировать/Разблокировать).
private void ToolStripMenuItem21_Click(object sender, EventArgs e)
{
//если название команды меню - "Заблокировать"
if (ToolStripMenuItem21.Text == "Заблокировать")
{
//блокируем поле
textBox1.ReadOnly = true;
//меняем название команды меню
ToolStripMenuItem21.Text = "Разблокировать";
}
//в противном случае
else
{
//разблокируем поле
textBox1.ReadOnly = false;
//меняем название команды меню
ToolStripMenuItem21.Text = "Заблокировать";
}
}
Иногда возникает необходимость создания нескольких режимов работы с программой. Например:
- для новичков - отображается минимальный набор команд;
- для продвинутых пользователей - полный набор команд;
- для администратора - полный набор команд + команды администрирования.
Или с точки зрения безопасности:
- для кладовщика - только набор команд работы со складом;
- для отдела кадров - набор команд для работы с персоналом;
- для бухгалтерии - набор команд по бухучету;
- для руководителя - полный набор команд.
Для этого в программе создаются разные компоненты MenuStrip и, в зависимости от того, кто зарегистрировался в программе, для главной формы в свойстве MainMenuStrip задается имя нужного компонента меню.
Компонент ContextMenuStrip
Данный компонент представляет собой контекстное меню, которое открывается щелчком правой кнопкой мыши на соответствующем компоненте. Принцип создания команд в таком компоненте абсолютно идентичен создания главного меню. Отличие в том, что данное меню не может иметь разделов (команд по горизонтали).
Часто команды контекстного меню повторяют команды главного меню. В этом случае не нужно для контекстного меню создавать обработчики событий заново. Достаточно выделить нужную команду контекстного меню и в событии Click из выпадающего списка выбрать обработчик нужной команды главного меню.
Если для разных компонентов вы планируете создавать разные контекстные меню с разными наборами команд, то нужно будет создать несколько таких компонентов.
После создания контекстного меню его необходимо присвоить нужному компоненту. Для этого у каждого компонента имеется свойство ContextmenuStrip, в котором с помощью выпадающего списка выбирают нужное контекстное меню.
Замечание: компонент TextBox и NumericUpDown имеют свроенные контекстные меню для выполнения основных операций с текстом. Если им назначить пользовательское контекстное меню, то оно заменит стандартное.
3. Панели инструментов и строка статуса
Панель инструментов предназначена для ускорения доступа пользователя к наиболее часто используемым функциям программной системы. панель инструментов обычно располагается под строкой меню и содержит набор кнопок, которые дублируют команды меню.
Для создания такой панели используется компонент ToolStrip. После добавления этого компонента, он отображается на отдельной панели под формой. При работе с компонентом Вам придется иметь дело со свойствами двух типов: свойствами самой панели и свойствами отдельного компонента на панели. Чтобы отобразить свойства панели, выделите компонент на панели под формой. Основные свойства компонента:
|
Свойство |
Описание |
|
Name |
Имя компонента для обращения к нему в коде |
|
Dock |
Задает размещение панели на форме. По умолчанию у верхнего края |
|
Items |
Коллекция компонентов на панели. Позволяет добавлять и редактировать компоненты |
|
LayoutStyle |
Задает вид расположения компонентов панели. По умолчанию - по горизонтали |
|
ShowItemToolTip |
Включает отображение всплывающих подсказок для компонентов на панели |
|
Text |
Задает надпись для компонентов на панели |
|
TextDirection |
Задает ориентацию написания названий компонентов на панели. По умолчанию - горизонтальная |
Основное свойство - Item, которое открывает окно редактора компонентов панели:

В левой части окна отображаются компоненты на панели. Можно добавить, удалить и изменить порядок следования компонентов с помощью соответствующих кнопок.
При добавлении компонента можно указать его тип. Добавить можно кнопку (наиболее часто используемый вариант), надпись, выпадающий список, разделитель, текстовое поле, индикатор выполнения.
В правой части отображаются свойства выделенного раздела. Набор этих свойств зависит от типа компонента. Опишем основные свойства для кнопки, так как этот компонент используется чаще всего:
|
Свойство |
Описание |
|
Name |
Имя компонента для обращения к нему в коде |
|
Alignment |
Выравнивание компонента относительно всей панели |
|
AutoToolTip |
Включает автоматическое отображение всплывающей подсказки для кнопки |
|
Checked |
Позволяет нажать кнопку (true) или отжать (false) |
|
CheckOnClick |
Включает для кнопки работу в виде флажка по клику (вкл/выкл) |
|
Enabled |
Включает или выключает признак активности кнопки. Если в каком-то режиме работы программы кнопка не имеет смысла, то ее можно сделать неактивной (будет отображаться серым цветом) |
|
Image |
Задает иконку для отображения на кнопке |
|
ImageAlign |
Задает выравнивание иконки на кнопке |
|
Text |
Задает название для кнопки. Чаще всего свойство не задают. Достаточно отображения иконки |
|
TextAlign |
Выравнивание текста на кнопке, если он задан |
|
TextDirection |
Задает ориентацию текста на кнопке, если он задан. По умолчанию - горизонтальная |
|
TextImageRelation |
Задает размещение текста и иконки внутри кнопки |
|
ToolTipText |
Задает текст всплывающей подсказки |
Так как кнопки часто дублируют некоторые команды меню, то писать для них обработчики событий не нужно. Необходимо для нужной кнопки в событии Click из выпадающего списка выбрать обработчик события нужной команды меню.
Существует возможность быстрого создания на панели инструментов набора кнопок для выполнения стандартных операций: Создать, Открыть, Сохранить, Вырезать, Копировать, Вставить, Помощь. Для этого выделите строку статуса, в правом верхнем углукомпонента нажмите на кнопку со стрелкой и в открывшемся окне щелкните на строке "Вставить стандартные элементы".

Строка статуса
Строка статуса обычно находится внизу окна приложения и предназначена для отображения вспомогательной информации о режимах работы программы. На строке могут располагаться различные компоненты, каждый из которых несет свою смысловую нагрузку.
Для создания такой панели используется компонент StatusStrip. После добавления этого компонента, он отображается на отдельной панели под формой. При работе с компонентом Вам придется иметь дело со свойствами двух типов: свойствами самой панели и свойствами отдельного компонента на панели. Чтобы отобразить свойства панели, выделите компонент на панели под формой. Основные свойства компонента:
|
Свойство |
Описание |
|
Name |
Имя компонента для обращения к нему в коде |
|
Name |
Имя компонента для обращения к нему в коде |
|
Dock |
Задает размещение строки статуса на форме. По умолчанию у нижнего края |
|
Items |
Коллекция компонентов на строке. Позволяет добавлять и редактировать компоненты |
|
LayoutStyle |
Задает вид расположения компонентов панели. По умолчанию - по горизонтали |
|
ShowItemToolTip |
Включает отображение всплывающих подсказок для компонентов на строке статуса |
Основное свойство - Item, которое открывает окно редактора компонентов панели:

В левой части окна отображаются компоненты на строке статуса. Можно добавить, удалить и изменить порядок следования компонентов с помощью соответствующих кнопок.
При добавлении компонента можно указать его тип. Добавить можно надпись (наиболее часто используемый вариант), выпадающий список, индикатор выполнения.
В правой части отображаются свойства выделенного раздела. Набор этих свойств зависит от типа компонента. Опишем основные свойства для надписи, так как этот компонент используется чаще всего:
|
Свойство |
Описание |
|
Name |
Имя компонента для обращения к нему в коде |
|
AutoToolTip |
Включает автоматическое отображение всплывающей подсказки для надписи |
|
IsLink |
Включает в надписи режим отображения текста как ссылки. Можно в событии Click надписи написать обработчик |
|
Text |
Задает текст для надписи |
|
TextAlign |
Выравнивание текста в надписи |
4. Системные диалоги
В программах Windows часто используются специальные диалоговые окна: Обзор папок, Открыть, Сохранить, Формат, Цвет, Печать. Эти окна всегда имеют одинаковый вид, так как являются стандартными системными диалогами Windows.
Для работы с системными диалогами существуют специальные компоненты, которые рассмотрим ниже. Все эти компоненты являются не видимыми и после их добавления на форму они отображаются на панели под формой.
Каждый такой компонент имеет свои свойства, но вызов таких диалогов выполняется с помощью стандартного кода вида:
//если диалог был вызван и пользователь в нем подтвердил выбор
if (диалог.ShowDialog()==DialogResult.OK)
//действия после вызова диалога;
Диалог форматирования символов
Компонент FontDialog вызывает диалоговое окно выбора атрибутов шрифта. В нем пользователь может выбрать имя шрифта, его стиль (начертание), размер и другие атрибуты.

Компонент имеет свойства:
|
Свойство |
Описание |
|
Name |
Имя компонента для обращения к нему в коде |
|
Color |
Выбранный в диалоге цвет символов |
|
Font |
Выбранныев диалоге параметры шрифта символов. Основное свойство компонента |
|
MaxSixe |
Максимально допустимый размер символов |
|
MinSize |
Минимально допустимый размер символов |
|
ShowApply |
Включает отображение в диалоге кнопки Применить. В этом случае обработчик для нее нужно писать в событии диалога Apply |
|
ShowColor |
Включает отображения в диалоге функции задания цвета символов |
|
ShowEffects |
Включает в диалоге отображение функции задания эффектов (зачеркнутый, подчеркнутый) |
Приведем примеры применения компонента FontDialog. Пусть ваше приложение включает поле textBox1, и кнопку с надписью "Формат", с помощью которой пользователь может открывать диалог форматирования текста. Если Вы добавили на форму компонент FontDialog с именем fontDialog1, тогда обработчик для кнопки может иметь вид:
private void button1_Click(object
sender, EventArgs e)
{
//если диалог был вызван и пользователь в нем подтвердил выбор
if (fontDialog1.ShowDialog()==DialogResult.OK)
//присваиваем выбранные параметры шрифта полю
textBox1.Font=fontDialog1.Font;
}
Если в Вы задали для компонента свойство ShowColor = true, то пользователь может задавать цвет символов. В этом случае цвет символов должен применяться отдельной командой. Допишем наш пример с учетом задания цвета символов:
private void button1_Click(object
sender, EventArgs e)
{
//если диалог был вызван и пользователь в нем подтвердил выбор
if (fontDialog1.ShowDialog()==DialogResult.OK)
{
//присваиваем выбранные параметры шрифта полю
textBox1.Font=fontDialog1.Font;
//присваиваем выбранный цвет символов
textBox1.ForeColor = fontDialog1.Color;
}
}
При вызове диалога в нем отображаются параметры шрифта, принятые в системе по умолчанию. Текстовое поле на форме может иметь другое форматирование, поэтому диалог должен отображать не форматирование по умолчанию, а текущее форматирование, заданное в поле. Для этого перед вызовом диалога ему нужно присвоить форматирование поля. нащш предыдущий пример может быть переписан так:
Однако, при вызове диалога возникает проблема, связанная с тем, что в окне диалога не всегда правильно отображается текущий формат поля. Это может привести к некорректной работе диалога. Для решения данной проблемы необходимо перед открытием диалога устанавливать в него текущий формат поля. Поэтому полный код для форматирования текста может иметь вид:
private void button1_Click(object
sender, EventArgs e)
{
//устанавливаем в диалог текущий формат поля
fontDialog1.Font=textBox1.Font;
//устанавливаем в диалог текущий цвет символов
fontDialog1.Color=textBox2.ForeColor;
//если диалог был вызван и пользователь в нем подтвердил выбор
if (fontDialog1.ShowDialog()==DialogResult.OK)
{
//присваиваем выбранные параметры шрифта полю
textBox1.Font=fontDialog1.Font;
//присваиваем выбранный цвет символов
textBox1.ForeColor = fontDialog1.Color;
}
}
Если вы установите в компоненте свойство ShowApply = true, то можете написать обработчик события Apply:
private void
fontDialog1_Apply(object sender, EventArgs e)
{
textBox1.Font=fontDialog1.Font;
textBox1.ForeColor = fontDialog1.Color;
}
Тогда пользователь может наблюдать изменения в поле, нажимая в диалоговом окне кнопку Применить не закрывая диалог. Это очень удобно, потому что позволяет пользователю правильно подобрать атрибуты шрифта.
В рассмотренных примерах меняется шрифт в поле textBox1. Аналогично можно указать любой другой компонент, имеющий свойство Font.
Диалог выбора цвета
Компонент ColorDialog вызывает стандартное диалоговое окно выбора цвета.

Компонент имеет свойства:
|
Свойство |
Описание |
|
Name |
Имя компонента для обращения к нему в коде |
|
AllowFullOpen |
Включает отображенив диалоге кнопки "Определить цвет" для задания любого оттенка |
|
Color |
Выбранный в диалоге цвет символов |
|
FullOpen |
Включает отображение диалога в полном виде. нт необходимости нажимать кнопку "Определить цвет" |
Для задания цвета из диалога необходимо свойствам BackColor или ForeColor нужного компонента присвоить свойство Color диалога.
Приведем пример использования компонента ColorDialog. Если вы хотите, чтобы пользователь мог итзменить цвет фонакакого-то компонента, например, цвет фона компонента textBox1, тогда это можно реализовать оператором
//если диалог был вызван и пользователь в нем подтвердил выбор
if (colorDialog1.ShowDialog()==DialogResult.OK)
//присваиваем выбранный цвет фону поля
textBox1.BackColor =
colorDialog1.Color;
Рассмотренный компонент ColorDialog вызывает стандартный диалог Windows. Однако нередко его возможности избыточны и пользователю удобнее выбирать цвет с помощью выпадающего списка. По умолчанию такого компонента в C# нет. Но, в случае необходмости, его можно добавить и использовать в проекте. Для этого скачайте файл класса ColorComboBox. В контекстном меню проекта выполните команду "Добавить - Существующий элемент" и укажите на диске скачанный файл класса. Нажмите клавишу F6. В результате проект будет перестроен, а на панели инструментов появится новый компонент ColorComboBox. Для получения выбранного цвета в списке нужно использовать записб вида:
Color.FromName(colorComboBox1.Text)
Пример. Пусть на форме имеется компонент ColorComboBox. Необходимо при выборе в нем цвета изменять фон формы. В событии SelectedIndexChanged списка введем код:
private void colorComboBox1_SelectedIndexChanged_1(object sender, EventArgs e)
{
BackColor = Color.FromName(colorComboBox1.Text);
}
Диалог выбора папки
Компонент FolderBrowserDialog позволяет открыть окно выбора папки, в котором отображается структура логических дисков и папок в виде дерева. Пользователь может указать существующую папку или создать новую.

Компонент имеет свойства:
|
Свойство |
Описание |
|
Name |
Имя компонента для обращения к нему в коде |
|
RootFolder |
Имя папки, от которой начинается обзор (корневая папка) |
|
SelectedPath |
Полный путь к выбранной в диалоге папке (основное свойство) |
|
ShowNewFolderButton |
Включает отображение в диалоге кнопки создания новой папки |
Для работы с данным диалогом необходимо иметь навыки работы с папками и и файлами. Данные навыки будут рассмотрены в лекции № 5. Р
Пример. Пусть пользователь в диалоге указывает нужную папку и в нее сохраняется содержимое поля textBox1 под именем result.txt. Команда сохранения содержимого поля в файл была рассмотрена в первом разделе этой лекции.
private void button1_Click(object sender, EventArgs e)
{
//если диалог был вызван и пользователь в нем подтвердил выбор
if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
//сохраняем содержимое поля в файл
File.WriteAllLines(folderBrowserDialog1.SelectedPath + "\\result.txt", textBox1.Lines);
}
Диалог открытия файла
Для открытия файла используют компонент OpenFileDialog, который отображает системный диалог, в котором пользователь может выбрать любой файл на диске.

Компонент имеет свойства:
|
Свойство |
Описание |
|
Name |
Имя компонента для обращения к нему в коде |
|
AddExtention |
Включает автоматическое добавления расширения к имени файла |
|
CheckFileExists |
Включает проверку на существование файла |
|
CheckPathExists |
Включает проверку существования пути к файлу |
|
DefaultExt |
Расширение, добавляемое по умолчанию к имени файла |
|
FileName |
Полное имя файла (основное свойство) |
|
Filter |
Задает список типов фалов в диалоге. Записывается в формате Название_типа|Маска_файла|Название_типа|Маска_файла Например: Текстовые файлы|*.txt|Форматированный текст|*.rtf |
|
FilterIndex |
Номер активного типа файла (нумерация с 1) |
|
InitialDirectory |
Задает папку по-умолчанию в диалоге |
|
Multiselect |
Включает возможность выбора нескольких файлов в диалоге |
|
RestoreDirectory |
Включает возможность возврата в исходную папку после закрытия диалога |
|
Title |
Текст заголовка окна диалога |
|
ValidateNames |
Включает проверку имени на использование недопустимых символов |
Например, загрузим файл через диалог в поле textBox1.
private void button1_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
textBox1.Lines = File.ReadAllLines(openFileDialog1.FileName);
}
Диалог сохранения файла
Для сохранения данных в файл используют компонент SaveFileDialog, который отображает системный диалог, в котором пользователь может выбрать папку, тип и указать имя файла для сохранения.

Компонент имеет свойства:
|
Свойство |
Описание |
|
Name |
Имя компонента для обращения к нему в коде |
|
AddExtention |
Включает автоматическое добавления расширения к имени файла |
|
CheckFileExists |
Включает проверку на существование файла |
|
CheckPathExists |
Включает проверку существования пути к файлу |
|
DefaultExt |
Расширение, добавляемое по умолчанию к имени файла |
|
FileName |
Полное имя файла (основное свойство) |
|
Filter |
Задает список типов фалов в диалоге. Записывается в формате Название_типа|Маска_файла|Название_типа|Маска_файла Например: Текстовые файлы|*.txt|Форматированный текст|*.rtf |
|
FilterIndex |
Номер активного типа файла (нумерация с 1) |
|
InitialDirectory |
Задает папку по-умолчанию в диалоге |
|
OverwritePrompt |
Включает выдачу запроса на перезапись существующего файла на диске |
|
RestoreDirectory |
Включает возможность возврата в исходную папку после закрытия диалога |
|
Title |
Текст заголовка окна диалога |
|
ValidateNames |
Включает проверку имени на использование недопустимых символов |
Например, сохраним содержимое поля textBox1 в файл через диалог.
private void button1_Click(object sender, EventArgs e)
{
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
File.WriteAllLines(saveFileDialog1.FileName, textBox1.Lines);
}
5. Форма регистрации и форма-заставка
Нередко в программах при запуске нужно пройти регистрацию, вводя пароль. При этом используются следующие требования:
Рассмотрим пример. Пусть имеется форма вида:

Пароль разбит на четыре группы по 5 символов. Пользователь набирает пароль, и курсор автоматически переходит между полями. Всего дается 5 попыток для ввода. Если пароль не верный, то программа завершает роботу.
Сначала для всех полей в свойствах PasswordC har необходимо указать символ «*». Это позволит спрятать на экране настоящие символы пароля.
Для того чтобы курсор автоматически переходил между полями при вводе пароля необходимо проверять, ввел ли пользователь в поле 5 символов, если да, то перейти в следующее поле. При вводе текста для текстового поля происходит событие TextChanged, в которой необходимо написать код:
private void textBox1_TextChanged(object sender, EventArgs e)
{
//если в первом поле 5 символов
if (textBox1.Text.Length == 5)
//переходим во второе поле
textBox2.Focus();
}
Аналогичный код пишем для других полей.
private void textBox2_TextChanged(object sender, EventArgs e)
{
if (textBox2.Text.Length == 5)
textBox3.Focus();
}
private void textBox3_TextChanged(object sender, EventArgs e)
{
if (textBox3.Text.Length == 5)
textBox4.Focus();
}
private void textBox4_TextChanged(object sender, EventArgs e)
{
//с четвертого поля переходим на кнопку
if (textBox4.Text.Length == 5)
button1.Focus();
}
Создание универсального кода для перехода по полям
Приведенные примеры повторяют один и тот же код, который отличается только именами компонентов. Дублирование одинакового кода увеличивает размер программы и затрудняет внесение изменений (что-то можно пропустить).
Можно написать более универсальный обработчик, в котором не будем использовать имен компонентов и для перехода на следующий компонент будем использовать стандартный метод SelectNextControl(). Для работы рассматриваемого примера, необходимо, чтобы порядок полей и кнопок на форме соответствовал нужному порядку перехода курсора.
В событии TextChanged первого поля напишем код:
private void textBox1_TextChanged(object sender, EventArgs e)
{
//если длина активного поля равна 5
if ((sender as Control).Text.Length == 5)
//переходим на следующий компонент на форме
this.SelectNextControl((sender as Control), true, false, false, false);
}
Выделите остальные поля и в событии TextChanged в выпадающем списке выберите обработчик такого же события для первого поля.
Обработка ввода пароля
Для кнопки ОК нужно написать код, в котором проверяется пароль. Если пароль верный, то открывается окно главной программы. Если пароль не верный, то дается еще одна попытка ввода пароля. Если пользователь сделал 5 неудачных попыток, то программа закрывается.
private void button1_Click(object sender, EventArgs e)
{
//если пароль верный
if (textBox1.Text + textBox2.Text + textBox3.Text + textBox4.Text == "11111222223333344444")
{
//создаем экземпляр второй формы
Form2 form2 = new Form2();
//отображаем вторую форму
form2.Show();
//скрываем форму регистрации
Hide();
}
//если пароль не верный
else
{
//считаем число попыток
k++;
//выдаем сообщение об ошибке
MessageBox.Show("Пароль не верный. Осталось попыток: "+(5-k).ToString(),
"Ошибка регистрации",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
//ставми курсор в первое поле
textBox1.Focus();
//если число попыток = 5
if (k == 5)
//закрываем программу
Close();
}
}
Для работы этого фрагмента необходимо выполнить несколько операций:
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
Application.Exit();
}
Создание формы заставки
Форма-заставка отображается на экране до запуска основной программы. Если запуск программы происходит долго, то появление формы-заставки сообщает пользователю, что идет запуск и нужно подождать.
Для создания формы заставки добавьте новую форму, в свойстве BackroundImage укажите файл с фоновым изображением, в свойстве BackgroundImageLayout задайте тип масштабирования изображения на форме, в свойстве FormBorderStyle отключите границы окна (None) .
Форма-заставка отображается до открытия главной формы.
Пример. Пусть форма-заставка имеет имя Form3. Откройте файл проекта Program.cs и перед командой Application.Run(...) введите код:
//создаем экземпляр формы
Form3 form3 = new Form3();
//показываем форму
form3.Show();
//делаем паузу в 2 секунды (2000 мс)
System.Threading.Thread.Sleep(2000);
//удаляем форму из памяти
form3.Dispose();
Вопросы для самоконтроля
1. Опишите принципы работы с текстовым полем в многострочном формате: свойства и методы.
2. Опишите принцип создания меню в программе.
3. Опишите принцип создания панели инструментов и строки статуса
4. Опишите принципы работы с диалогами форматирования шрифта и выбора цвета
5. Опишите принцип работы с диалогами выбора папки и работы с файлами
6. Как создать форму регистрации в программе?
7. Как создать форму-заставку в программе?