Лекция 8
4.3. Использование элементов управления и компонентов
Наряду с формами важную часть пользовательского интерфейса составляют элементы управления. Это графические инструменты, которые формируют либо дополняют функциональность приложения. В их можно перетаскивать на форму с панели Toolbox. Кроме того, на этой же панели расположены компоненты, реализующие специализированные операции по взаимодействию с приложением. Компоненты, как и элементы управления, представляют собой готовые блоки, инкапсулирующие определенную функциональность. Основное отличие между ними в том, что при выполнении программы элементы управления видимы, а компоненты – нет, либо их внешний вид отличается от представления в режиме разработки.
4.3.1. Работа с элементами управления
Для размещения на форме элементов управления можно использовать дизайнер. Он в режиме разработки на основе текста программы отображает графическое представление формы, близкое к ее виду во время выполнения. При размещении нового элемента на форме связанный с ним код автоматически добавляется к приложению. Мышью можно менять положение и размеры элементов управления на форме. Эти и другие их публичные свойства доступны для настройки в панели Properties. Дизайнер автоматически вносит соответствующие изменения в текст программы.
Аналогично можно работать и с компонентами. Поскольку у них нет обычного графического интерфейса, они в дизайнере попадают не на поверхность формы, а в область компонентов. Она находится внизу окна дизайнера и предоставляет специальный графический интерфейс для манипулирования свойствами компонентов.
При размещении на форме элементов управления важно установить правильный порядок передачи фокуса между ними (tab order), который будет действовать во время работы пользователя (например, при нажатии им клавиши Tab). Этот порядок можно задавать с помощью целочисленного свойства TabIndex, содержащегося в элементах управления. Чем меньше значение TabIndex, тем раньше элемент получает фокус. Если у нескольких элементов эти значения совпадают, то первым получает фокус элемент переднего плана или ближайший к нему. Чтобы размещенный на форме элемент управления переместить на передний или задний план, достаточно щелкнуть его правой кнопкой и выбрать соответственно Bring To Front или Send To Back. В Visual Studio предусмотрен также графический инструмент для установки порядка передачи фокуса (пункт Tab Order меню View). Некоторые элементы управления, такие, как PictureBox, не могут получать фокус, поэтому у них нет свойства TabIndex.
Элементы управления генерируют разнообразные события, отражающие те или иные обстоятельства их взаимодействия с пользователем. Visual Studio посредством панели Properties позволяет легко создавать обработчики событий, связанных с элементами управления и компонентами. Можно также назначить для обработки события готовый метод, выбрав его из выпадающего списка. Кроме того, для каждого элемента существует событие по умолчанию (обычно генерируемое наиболее часто). Например, событием по умолчанию для элемента управления Button является Click, для CheckBox – CheckChanged. Создать обработчик события по умолчанию особенно просто – для этого достаточно сделать двойной щелчок на элементе в окне дизайнера. В результате в код добавляется шаблон обработчика, который можно дополнить собственным кодом.
Возможности разработчика не ограничены элементами управления из библиотеки базовых классов. NET Framework. Кроме них разрешается применять нестандартные элементы и компоненты, созданные сторонними специалистами. Добавив новые элементы управления на инструментальную панель Toolbox, можно сделать их доступными в среде разработки. Чтобы это проделать, достаточно щелкнуть правой кнопкой нужную вкладку панели Toolbox и выбрать из контекстного меню команду Customize Toolbox. При этом откроется окно, в котором будут показаны все компоненты, зарегистрированные в системе. Они распределены по двум группам – одна отображает. NET-компоненты, а другая – унаследованные компоненты СОМ.
4.3.2. Вложенные элементы управления и контейнеры
Некоторые элементы управления, называемые контейнерами (container controls), способны содержать другие элементы управления. К контейнерам относятся Panel, GroupBox и TabControl. Саму форму также можно считать контейнером. Контейнеры позволяют логически группировать и упорядочивать элементы управления на формах. Применение контейнеров облегчает создание интерфейса, выдержанного в едином стиле.
Изменение свойств контейнера отражается на его вложенных элементах управления. Например, положив
GroupBox. Enabled = false;
можно автоматически сделать недоступными все вложенные элементы. Свойства контейнера, определяющие внешний вид, такие, как BackColor, ForeColor, Visible и Font, также действуют на вложенные элементы управления. Тем не менее, любое свойство вложенного элемента можно переопределить вручную.
Перемещение контейнера на форме происходит вместе с его вложенными элементами. Элементы управления GroupBox и Panel в определенном смысле делят форму на отдельные «подформы». У GroupBox есть заголовок, позволяющий аннотировать группу вложенных в него элементов управления, текст заголовка определяется свойством Text. У Panel заголовка нет, но он поддерживает прокручивание содержимого. Чтобы включить полосы прокрутки, достаточно установить его свойство AutoScroll в true.
Контейнер TabControl позволяет упорядочивать элементы управления путем их размещения на вкладках с ярлычками, напоминающих разделители записной книжки. TabControl состоит из нескольких элементов TabPage, на которых, в свою очередь, могут располагаться другие элементы управления. Элементы TabPage объединены в свойстве TabPages, которое является набором (в смысле п.3.6.3). Чтобы получить визуальный доступ к любому из объектов TabPage, достаточно щелкнуть вкладку, которая его представляет.
Элемент управления TabPage похож на Panel: он также поддерживает прокрутку и создает внутри формы-контейнера «вложенные формы», в свою очередь способные быть контейнерами для других элементов. Элементы управления TabPage можно добавлять к TabControl или удалять посредством свойства TabPages. При выборе в окне дизайнера свойства TabPages открывается редактор наборов, позволяющий добавлять к TabControl элементы управления TabPage и устанавливать свойства для любого из них в визуальном режиме.
Многие элементы управления поддерживают свойства Anchor и Dock, определяющие их поведение внутри формы или другого контейнера. Установленное свойство Anchor выдерживает постоянное расстояние между границами элемента управления и границами формы, даже если размеры формы меняются. Свойство Dock позволяет пристыковать элемент управления к одному из краев формы либо заполнить им всю форму. При изменении размеров формы размеры пристыкованных элементов управления автоматически редактируются. Во время разработки значения свойств Anchor и Dock можно задавать в окне Properties в визуальном режиме.
Любой элемент управления, способный выполнять функцию контейнера (в том числе и форма), поддерживает набор всех его вложенных элементов. У этого набора есть свойство Count, возвращающее количество элементов, и целочисленный индексатор для доступа к элементам набора. У набора также имеются члены-методы (Add, Remove, RemoveAt), позволяющие динамически добавлять и удалять его элементы. Например,
Control aControl;
aControl = myForm. Controls[3];
Label aLabel = new Label ();
aLabel. Text = "Эта метка добавлена динамически!";
myForm. Controls. Add (aLabel);
myForm. Controls. Remove ("Button1");
myForm. Controls. RemoveAt(3);
Button aButton = new Button();
myTabControl. TabPages[1].Controls. Add (aButton);
4.3.3. Провайдеры дополнительных свойств
Это специализированные компоненты, расширяющие совокупность стандартных свойств элементов управления.
Рассмотрим для примера компонент ToolTipProvider. После добавления экземпляра этого компонента все остальные элементы управления, размещенные на данной форме, получают новое свойство, которое можно просматривать и устанавливать в окне Properties. Там оно отображается под именем ToolTip on <имя провайдера>, где «имя провайдера» – имя данного экземпляра ToolTipProvider. Если во время выполнения программы навести указатель мыши на какой-нибудь элемент управления, около него в желтом прямоугольнике отображается значение строкового свойства ToolTip.
Провайдеры дополнительных свойств обычно применяются для предоставления пользователям дополнительной информации во время выполнения. В частности, ToolTipProvider отображает всплывающие подсказки. К провайдерам дополнительных свойств также относятся классы HelpProvider и ErrorProvider.
В действительности свойства, предоставляемые компонентами-провайдерами, содержатся в самих этих компонентах, а не в элементах управления, чьи возможности они расширяют. Поэтому такие свойства не являются истинными свойствами элементов и к ним нельзя обращаться во время выполнения, как к обычным свойствам. Провайдеры дополнительных свойств поддерживают специальные методы, которые позволяют получать доступ к предоставляемым ими свойствам. Согласно правилам, эти методы всегда называются Get<имя свойства> и Set<имя свойства>. Так, у ToolTipProvider есть методы GetToolTip и SetToolTip. Вызывая эти методы, можно получать и динамически изменять текст всплывающей подсказки каждого элемента управления. Оба метода принимают в качестве аргумента ссылку на элемент управления, а методу Set дополнительно требуется новое значение свойства ToolTip.
Например:
string myToolTip;
myToolTip = toolTip1.GetToolTip(button1);
toolTip1.SetToolTip (button1, "Нажмите эту кнопку для получения помощи");
Резюме
· Порядок передачи фокуса для элементов формы можно устанавливать двумя способами: через значение свойства TabIndex либо в визуальном режиме выбрав в меню View элемент Tab Order.
· Обработчики событий элементов управления создаются так же, как и обработчики событий формы. Обработчик вызывается каждый раз, когда генерируется обрабатываемое им событие.
· Разрешается добавлять на панель Toolbox дополнительные элементы управления. Для этого следует щелкнуть правой кнопкой нужную секцию панели Toolbox и выбрать необходимый элемент управления из списка либо найти DLL-файл с нужным элементом управления.
· Некоторые элементы управления могут быть контейнерами для других элементов, позволяя объединять элементы формы в группы. К ним относятся Panel, GroupBox, TabPage (в составе TabControl)
· Свойства Dock и Anchor реализуют автоматическое изменение размеров и расположения элементов управления на форме. Установив свойство Dock, можно пристыковать элемент управления к границе формы. Свойство Anchor задает для элемента управления «плавающее» или фиксированное размещение, а также разрешает или запрещает менять его размеры при изменении размеров формы или другого контейнера.
· Для динамического добавления элементов управления во время выполнения служит набор элементов формы. Чтобы добавить элемент управления к форме, следует объявить его, создать экземпляр и добавить созданный экземпляр к набору элементов формы.
· Компоненты-провайдеры предоставляют дополнительные свойства времени разработки элементам управления, размещенным на форме. Эти свойства применяются для выдачи пользователю дополнительной информации, например, подсказок и справки.
4.4. Меню
С помощью этого компонента пользователям обычно открывается доступ к функциям приложения. В хорошо организованном меню нетрудно найти необходимые функции. Напротив, к неудачно сконструированному меню пользователи будут обращаться лишь в случае крайней необходимости.
При разработке меню необходимо учитывать логику приложения. Элементы меню следует группировать в соответствии с функциональностью, которую они представляют. Использование быстрых клавиш для доступа к элементам меню дополнительно облегчает работу с приложением.
Главное меню формы обычно создается во время разработки при помощи компонента System. Windows. Forms.MainMenu. Этот компонент содержит набор элементов управления System. Windows. Forms.MenuItems, формирующих графическое представление пунктов меню во время выполнения, и управляет этим набором. Таким образом, компонент MainMenu позволяет легко и быстро создать меню для формы.
Компонент MainMenu позволяет выполнять следующие действия во время разработки:
· создавать новые меню;
· добавлять к существующим меню новые элементы;
· менять свойства меню и отдельных его элементов в окне Properties;
· создавать обработчики Click и других событий элементов меню.
Помимо главного меню формы, существуют контекстные меню. Контекстное меню можно вызывать щелчком правой кнопки мыши. Для его создания предназначен компонент System. Windows. Forms.ContextMenu, который редактируется аналогично MainMenu. Чтобы связать контекстное меню с формой или элементом управления, достаточно в их свойство ContextMenu занести имя этого меню.
4.4.1. Создание меню во время разработки
Для создания меню формы достаточно поместить на нее компонент MainMenu, который затем появится в области компонентов. На самой же форме возникает полоска с прямоугольным полем, содержащим надпись «Туре Неrе». Для создания нового пункта меню достаточно ввести текст в это поле. После добавления первого элемента снизу и справа от него появляются новые поля, позволяющие создавать новые элементы меню. Вид меню в период разработки почти не отличается от такового во время выполнения.
При добавлении к меню нового элемента дизайнер создает экземпляр объекта MenuItem, у которого имеются собственные свойства и члены, доступные для редактирования в окне Properties. Свойство Text задает текст данного элемента меню, отображаемый во время выполнения. Свойство Name определяет имя объекта меню, которое может использоваться для ссылок на него в коде. При создании объекта это свойство автоматически получает значение по умолчанию, которое затем может быть изменено.
При необходимости элементы меню можно отделять друг от друга рельефной линией. Разделители позволяют упорядочивать меню, состоящее из множества элементов, разбивая его на логические группы. Чтобы добавить к меню разделитель, достаточно ввести дефис вместо имени элемента меню, после чего этот элемент становится разделителем.
Доступ к элементам меню или подменю может быть реализован с клавиатуры. Для этого им могут назначаться клавиши доступа (access keys) и быстрые клавиши (shortcut keys).
Клавиша доступа – это выделенный символ в тексте элемента меню. Для создания клавиши доступа достаточно в строковом свойстве Text перед нужным символом поместить &. В самом элементе меню этот символ будет выделен подчеркиванием. Тогда доступ к данному элементу при активизированном меню можно осуществить одной клавишей доступа. Для активизации главного меню формы можно использовать Alt. Например, во многих приложениях Alt, F открывают меню File.
Быстрые клавиши ускоряют доступ к командам меню, позволяя выбирать их не открывая самого меню. Эта возможность экономит время при вызове часто используемых команд. Комбинация быстрых клавиш может состоять из одной или нескольких клавиатурных, например F1, Insert, Delete или Ctrl+A, Ctrl+F1, Ctrl+Shift+X. Для назначения быстрых клавиш элементу меню используется его свойство Shortcut (например, в окне Properties). Быстрые клавиши отображаются справа от текста элемента меню, для которого они назначены. Если для элемента меню свойство ShowShortcut установлено в false, то быстрые клавиши для него не отображаются.
Для элементов контекстного меню также можно задавать быстрые клавиши, однако поддержка клавиш доступа для них не предусмотрена.
Управлять доступностью пунктов меню можно следующими свойствами класса MenuItem:
public bool Enabled, Visible;
Установив Enabled = false, можно деактивировать пункт меню, запрещая ему реагировать на действия пользователя, в том числе на клавиши доступа и быстрые клавиши. Деактивированные элементы меню выделяются бледно-серым цветом. Чтобы сделать элемент меню невидимым, нужно установить Visible = false. Тогда соответствующий элемент удаляется из меню, а его вложенные элементы становятся недоступными.
Можно предоставить пользователю дополнительную информацию, снабжая элементы меню флажками или переключателями. Для этих манипуляций соответственно можно использовать свойства
public bool Checked, RadioCheck;
Значение Checked = true снабжает элемент меню флажком, который отображается справа от текста элемента. Флажки позволяют пометить выбранные параметры. Вместо флажка можно отображать переключатель (в виде крупной точки). Для этого достаточно при установленном флажке Checked задать еще RadioCheck = true. Заметим, что переключатели обычно применяются для выбора взаимоисключающих параметров, например, цвета фона. Чтобы при установке одного переключателя остальные сбрасывались, придется дополнительно написать соответствующий код.
4.4.2. События элементов меню
Процедура создания обработчика события элемента меню не отличается от таковой для других элементов управления. Рассмотрим кратко следующие события класса MenuItem:
public event EventHandler Click, Select, Popup;
С элементами меню чаще всего применяют событие Click. Код обработчика этого события исполняется в ответ на щелчок соответствующего элемента меню, а также при нажатии назначенных ему клавиш.
Событие Select генерируется при выделении элемента меню подсветкой с помощью мыши или клавиш доступа. Для этого события можно написать обработчик, отображающий подробное описание команды при выборе соответствующего элемента меню.
Событие Popup элемента меню происходит непосредственно перед отображением его вложенных элементов. Это событие позволяет активировать и деактивировать отдельные элементы группы команд меню перед отображением этой группы во время выполнения.
4.4.3. Изменение меню во время выполнения
Меню можно изменять динамически в зависимости от условий времени выполнения программы. Для этого, в частности, можно менять значения рассмотренных выше свойств класса MenuItem.
Для динамического формирования меню бывает полезным использование свойства MenuItems, которое представляет собой набор элементов данного меню или дочерних элементов пункта меню. Как и любой другой набор, он содержит методы для добавления и удаления своих составляющих.
Во время выполнения существует также возможность копирования (клонирования) имеющихся элементов меню. Например, можно клонировать элемент главного меню Edit (со всеми вложенными элементами) и поместить его копию в контекстное меню некоторого элемента управления. Для решения этой задачи, в частности, применяется метод CloneMenu. Этот метод создает копию заданного элемента меню со всеми его членами, к которым относятся вложенные элементы меню, свойства и обработчики событий. В результате получается клон, способный обрабатывать все события, которые обрабатывал оригинал. Созданное таким образом контекстное меню можно связать с некоторым элементом управления. Например:
myContextMenu = new ContextMenu ();
myContextMenu. MenuItems. Add (fileMenuItem. CloneMenu () );
myButton. ContextMenu = myContextMenu;
Иногда во время выполнения требуется объединить содержимое нескольких меню в одно. Для этого применяется метод MergeMenu, который способен объединять содержимое двух меню (например, главного и контекстного). Порядок объединения отдельных элементов задается целочисленным свойством MergeOrder класса MenuItem. Например:
mainMenu1.MergeMenu (contextMenul);
Можно также динамически создавать и добавлять к меню новые элементы во время выполнения. Например, к меню File имеет смысл добавить элементы, отображающие путь к недавно открывавшимся файлам. У новых элементов меню изначально нет обработчиков событий, однако их можно подготовить заранее. Например, можно заранее написать метод для обработки события Click, который передать во время выполнения конструктору элемента меню в качестве аргумента. Этот метод должен быть процедурой (void) с сигнатурой обработчика события. Например:
public void myClick (object sender, System. EventArgs e)
{
// Реализация опущена
}
MenuItem myItem;
myItem = new MenuItem ("Пункт меню 1", new EventHandler(myClick));
MainMenu1.MenuItems. Add (myItem);
Резюме
· Меню – это интерфейсный компонент, с помощью которого легко открывается доступ к функциям приложения. Компонент MainMenu позволяет оперативно создать меню для приложения. Разделители, клавиши доступа и быстрые клавиши расширяют его возможности.
· Контекстное меню удобно для доступа к набору команд, который зависит от текущего контекста приложения. Контекстное меню создается средствами компонента ContextMenu аналогично главному меню.
· Во время выполнения программы свойства пунктов меню можно менять, динамически настраивая интерфейс пользователя. Можно активировать, деактивировать и скрывать элементы меню, а также снабжать их флажками или переключателями.
· Методы CloneMenu, MergeMenu помогают динамически формировать структуру меню, создавая новые меню на основе имеющихся и объединяя существующие меню.
· Можно динамически создавать новые пункты меню со ссылкой на подготовленные ранее обработчики и добавлять их к существующим меню.


