Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЛР9.doc
Скачиваний:
24
Добавлен:
21.09.2019
Размер:
4.54 Mб
Скачать

Событийно-управляемое программирование

В основу Windows положен принцип событийного управления. Это значит, что и сама система, и приложения после запуска ожидают действий пользователя и реагируют на них заранее заданным образом. Любое действие пользователя (нажатие клавиши на клавиатуре, щелчок кнопкой мыши, перемещение мыши) называется событием. Структура программы, управляемой событиями, изображена на рисунке 9.1.

Рис. 9.1 ­­­­­­­­­­­­­- Структура программы, управляемой событиями

Событие воспринимается Windows и преобразуется в сообщение — запись, содержащую необходимую информацию о событии (например, какая клавиша была нажата, в каком месте экрана произошел щелчок мышью). Сообщения могут поступать не только от пользователя, но и от самой системы, а также от активного или других приложений. Определен достаточно широкий круг стандартных сообщений, образующий иерархию, кроме того, можно определять собственные сообщения.

Сообщения поступают в общую очередь, откуда распределяются по очередям приложений. Каждое приложение содержит цикл обработки сообщений, который выбирает сообщение из очереди и через операционную систему вызывает подпрограмму, предназначенную для его обработки (рис. 9.2). Таким образом, Windows-приложение состоит из главной программы, обеспечивающей инициализацию и завершение приложения, цикла обработки сообщений и набора обработчиков событий.

Рис. 9.2 - Структура Windows-приложения

Среда Visual Studio.NET содержит удобные средства разработки Windows-приложений, выполняющие вместо программиста рутинную работу — создание шаблонов приложения и форм, заготовок обработчиков событий, организацию цикла обработки сообщений и т. д. Рассмотрим эти средства.

Шаблон Windows-приложения

Создадим новый проект (FileNewProject), выбрав шаблон Windows Application (рисунок 9.3). После более длительных раздумий, чем для консольного приложения, среда сформирует шаблон Windows-приложения. Первое отличие, которое бросается в глаза, — вкладка заготовки формы Form1.cs[Design], расположенная в основной части экрана. Форма представляет собой окно и предназначена для размещения компонентов (элементов управления) — меню, текста, кнопок, списков, изображений и т. д.

Рис. 9.3 - Выбор шаблона проекта

Среда создает не только заготовку формы, но и шаблон текста приложения. Перейти к нему можно, щелкнув в окне Solution Explorer (ViewSolution Explorer) правой кнопкой мыши на файле Form1.cs и выбрав в контекстном меню команду View Code. При этом откроется вкладка с кодом формы, который, за исключением комментариев, приведен в листинге 9.1. Представлять себе, что написано в вашей программе, весьма полезно, поэтому давайте внимательно рассмотрим этот текст.

Листинг 9.1. Шаблон Windows-приложения

using System;

using System.Drawing;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

using System.Data;

namespace WindowsApplication1

{

public class Form1 : System.Windows.Forms.Form

{

private System.ComponentModel.Container components = null;

public Form1()

{

InitializeComponent();

}

protected override void Dispose(bool disposing)

{

if (disposing)

{

if (components != null)

{

components.Dispose();

}

}

base.Dispose(disposing);

}

#region Windows Form Designer generated code

private void InitializeComponent()

{

this.components = new System.ComponentModel.Container();

this.Size = new System.Drawing.Size(300, 300);

this.Text = "Form1";

}

#endregion

static void Main()

{

Application.Run(new Form1());

}

}

}

Приложение начинается с директив использования пространств имен библиотеки .NET. Для пустой формы, не содержащей ни одного компонента, необходимыми являются только две директивы:

using System;

using System.Windows.Forms;

Остальные директивы добавлены средой «на вырост». С пространством имен System вы уже знакомы. Пространство System.Windows.Forms содержит огромное количество типов, являющихся строительными блоками Windows-приложений. Список наиболее употребительных элементов этого пространства имен приведен в таблице 9.1, а часть иерархии — на рис. 9.4.

Таблица 9.1 - Основные типы Windows.Forms

Класс

Назначение

Application

Класс Windows-приложения. При помощи методов этого класса можно обрабатывать Windows-сообщения, запускать и прекращать работу приложения и т. п.

ButtonBase, Button, CheckBox, ComboBox, DataGrid, GroupBox, ListBox, LinkLabel, PictureBox

Примеры классов, представляющих элементы управления (компоненты): базовый класс кнопок, кнопка, флажок, комбинированный список, таблица, группа, список, метка с гиперссылкой, изображение

Form

Класс формы — окно Windows-приложения

ColorDialog, FileDialog, FontDialog, PrintPreviewDialog

Примеры стандартных диалоговых окон для выбора цветов, файлов, шрифтов, окно предварительного просмотра

Menu, MainMenu, MenuItem, ContextMenu

Классы выпадающих и контекстных меню

Clipboard, Help, Timer, Screen, ToolTip, Cursors

Вспомогательные типы для организации графических интерфейсов: буфер обмена, помощь, таймер, экран, подсказка, указатели мыши

StatusBar, Splitter, ToolBar, ScrollBar

Примеры дополнительных элементов управления, размещаемых на форме: строка состояния, разделитель, панель инструментов и т. д.

Рис. 9.4 - Элементы управления Windows.Forms

Мы будем изучать типы пространства имен Windows.Forms по мере необходимости.

Продолжим рассмотрение листинга 9.1. В нем описан класс Form1, производный от класса Form. Он наследует от своего предка множество элементов, которые мы рассмотрим в следующих разделах. В самом классе Form1 описано новое закрытое поле components — контейнер для хранения компонентов, которые можно добавить в класс формы.

Конструктор формы вызывает закрытый метод InitializeComponent, автоматически формируемый средой (код метода скрыт между директивами препроцессора #region и #endregion). Этот метод обновляется средой при добавлении элементов управления на форму, а также при изменении свойств формы и содержащихся на ней элементов. Например, если изменить цвет фона формы с помощью окна свойств (Properties), в методе появится примерно такая строка:

this.BackColor = System.Drawing.SystemColors.AppWorkspace;

Метод освобождения ресурсов Dispose вызывается автоматически при закрытии формы. Точка входа в приложение, метод Main, содержит вызов статического метода Run класса Application. Метод Run запускает цикл обработки сообщений и выводит на экран форму, новый экземпляр которой передан ему в качестве параметра.

Процесс создания Windows-приложения состоит из двух основных этапов:

  • Визуальное проектирование, то есть задание внешнего облика приложения.

  • Определение поведения приложения путем написания процедур обработки событий.

Визуальное проектирование заключается в помещении на форму компонентов (элементов управления) и задании их свойств и свойств самой формы с помощью окна свойств. Если его не видно, можно воспользоваться командой меню ViewProperties Window. Свойства отображаются либо в алфавитном порядке, либо сгруппированными по категориям. Способ отображения выбирается с помощью кнопок, расположенных в верхней части окна свойств (рис. 9.5).

Рис. 9.5 - Окно свойств

Самый простой способ размещения компонента — двойной щелчок на соответствующем значке палитры компонентов Toolbox (если ее не видно, можно воспользоваться командой меню ViewToolbox), при этом компонент помещается на форму. Затем компонент можно переместить и изменить его размеры с помощью мыши. Можно также сделать один щелчок на палитре и еще один щелчок в том месте формы, где планируется разместить компонент. В окне свойств отображаются свойства выбранного в данный момент компонента (он окружен рамкой).

Задание свойств выполняется либо выбором имеющихся в списке вариантов, либо вводом требуемого значения с клавиатуры. Если около имени свойства стоит значок +, это означает, что свойство содержит другие свойства. Они становятся доступными после щелчка на значке. Пример формы, на которой размещены компоненты с вкладки палитры Windows Forms, показан на рис. 9.6. Эти компоненты описаны в разделе «Элементы управления» .

Рис. 9.6 - Форма с размещенными на ней компонентами

Определение поведения программы начинается с принятия решений, какие действия должны выполняться при щелчке на кнопках, вводе текста, выборе пунктов меню и т. д., иными словами, по каким событиям будут выполняться действия, реализующие функциональность программы.

Заготовка шаблона обработчика события формируется двойным щелчком на поле, расположенном справа от имени соответствующего события на вкладке Events окна свойств, при этом появляется вкладка окна редактора кода с заготовкой соответствующего обработчика (вкладка Events отображается в окне свойств при щелчке на кнопке с желтой молнией, как показано на рис. 9.5).

Для каждого класса определен свой набор событий, на которые он может реагировать. Наиболее часто используемые события:

  • Activated — получение формой фокуса ввода;

  • Click, DoubleClick — одинарный и двойной щелчки мышью;

  • Closed — закрытие формы;

  • Load — загрузка формы;

  • KeyDown, KeyUp — нажатие и отпускание любой клавиши и их сочетаний;

  • KeyPress — нажатие клавиши, имеющей ASCII-код;

  • MouseDown, MouseUp — нажатие и отпускание кнопки мыши;

  • MouseMove — перемещение мыши;

  • Paint — возникает при необходимости прорисовки формы.

В листинге 9.2 приведен текст программы, сформированной средой после размещения на форме компонентов, представленных на рис. 9.5, и выборе для кнопки события Click, а для поля ввода — события KeyPress. Из листинга для удобства восприятия удалены лишние элементы.

Листинг 9.2. Шаблон приложения с двумя компонентами и заготовками обработчиков событий

using System;

using System.Drawing;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

using System.Data;

namespace WindowsApplication1

{

public class Form1 : System.Windows.Forms.Form // 0

{

private System.Windows.Forms.TextBox textBox1; // 1

private System.Windows.Forms.Button button1; // 2

private System.ComponentModel.Container components = null;

public Form1()

{

InitializeComponent();

}

protected override void Dispose(bool disposing) { ... }

#region Windows Form Designer generated code

private void InitializeComponent()

{

this.textBox1 = new System.Windows.Forms.TextBox(); // 3

this.button1 = new System.Windows.Forms.Button(); // 4

this.SuspendLayout(); // 5

//

// textBox1

//

this.textBox1.Location = new System.Drawing.Point(24, 16);

this.textBox1.Name = "textBox1";

this.textBox1.Size = new System.Drawing.Size(240, 20);

this.textBox1.TabIndex = 0;

this.textBox1.Text = "textBox1";

this.textBox1.KeyPress += new // 6

System.Windows.Forms.KeyPressEventHandler(this.textBox1_KeyPress);

//

// button1

//

this.button1.Location = new System.Drawing.Point(192, 80);

this.button1.Name = "button1";

this.button1.TabIndex = 1;

this.button1.Text = "button1";

this.button1.Click += new // 7

System.EventHandler(this.button1_Click);

//

// Form1

//

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);

this.ClientSize = new System.Drawing.Size(292, 126);

this.Controls.Add(this.button1); // 8

this.Controls.Add(this.textBox1); // 9

this.Name = "Form1";

this.Text = "Form1";

this.ResumeLayout(false); // 10

}

#endregion

static void Main()

{

Application.Run(new Form1());

}

private void button1_Click(object sender, System.EventArgs e)

{

// 11

}

private void textBox1_KeyPress(object sender,

System.Windows.Forms.KeyPressEventArgs e)

{

// 12

}

}

}

Рассмотрим текст программы. В операторах 1 и 2 в класс формы добавляется два закрытых поля: строка ввода типа TextBox и кнопка типа Button. Эти типы определены в пространства имен System.Windows.Forms, которое подключяется в соответствующей директиве using, поэтому можно записать эти и соседние строки проще:

public class Form1 : Form // 0

{

private TextBox textBox1; // 1

private Button button1; // 2

private Container components = null;

Чаще всего программист изменяет имена, присваиваемые элементам средой, более осмысленными. Это можно сделать, задав новое значение свойства Name элемента. Самое важное происходит в методе InitializeComponent.

В операторах 3 и 4 создаются экземпляры компонентов, затем для каждого из них задаются свойства, определяющие их положение, размер, вид и т. д. Обратите внимание на операторы 6 и 7. В них регистрируются обработчики соответствующих событий. Механизм обработки событий тот же, что мы рассматривали в главе 10 — он описывается моделью «публикация — подписка».

Например, для кнопки button1, в составе которой есть событие Click, регистрируется обработчик button1_Click, являющийся закрытым методом класса Form1. Это значит, что при наступлении события нажатия на кнопку (об этом сообщит операционная система) будет вызван соответствующий обработчик.

Имя обработчика формируется средой автоматически из имени экземпляра компонента и имени события. Обратите внимание, что обработчикам передаются два параметра: объект-источник события и запись, соответствующая типу события.

После создания экземпляров компонентов и настройки их свойств компоненты заносятся в коллекцию, доступ к которой выполняется через свойство Controls (операторы 8 и 9). Если этого не сделать, компоненты не будут отображаться на форме. Коллекция поддерживает методы добавления и удаления компонентов (Add и Remove).

Таким образом, для размещения компонента на форме необходимо выполнить три действия:

  • Создать экземпляр соответствующего класса.

  • Настроить свойства экземпляра, в том числе зарегистрировать обработчик событий.

  • Поместить экземпляр в коллекцию компонентов формы.

Операторы 5 и 10 используются для того, чтобы все изменения в свойства элементов вносились одновременно. Для этого в операторе 5 внесение изменений «замораживается», а в операторе 10 разрешается.

В теле обработчиков событий (операторы 11 и 12) программист может, наконец-то, самостоятельно написать код, который будет выполняться при наступлении события. Добавим в эти строки операторы, выводящие окна сообщений с соответствующим текстом:

MessageBox.Show("Нажата кнопка button1"); // 11

MessageBox.Show("Нажата клавиша " + e.KeyChar); // 12

Здесь используется простейший вариант статического метода Show класса MessageBox, определенного в пространстве имен System.Windows.Forms. Существуют более десяти перегруженных вариантов этого метода, позволяющих варьировать вид выводимой информации, например, задать заголовок окна и наименования отображаемых на нем кнопок.

Прежде чем приступить к изучению форм и элементов управления, размещаемых на формах, необходимо рассмотреть их общего предка — класс Control.