В этом параметре скрывается информация, сопутствующая событию (вспомните wParam и lParam в каркасе API). Так, в аргументе PaintEventArgs спрятан контекст устройства для рисования (вспомните HDC). Он нас интересует, так как позволяет рисовать в контексте, не зависящем от физического устройства (монитора или принтера). Контекст устройства для рисования замаскирован в объекте класса Graphics. Мы должны его выудить из параметра (PaintEventArgs e) для того, чтобы получить возможность для рисования. Итак, для рисования мы должны:
· Создать своего делегата и дать ему задание (указать адрес функции обработки события),
· Добавить его в список делегатов события Paint,
· Добавить в класс MyForm саму функцию обработки события.
Эти действия можно автоматизировать с помощью инструмента студии (мастера вставок).
1. Поставьте клавиатурный фокус в конец тела конструктора.
2. Введите имя события и два символа операции добавки (в коллекцию делегатов): Paint +=. Мастер откликнется и подскажет, что делать дальше.
3. Нажмите Tab. Мастер создаст делегата с нужной сигнатурой.
4. Еще раз нажмите Tab. Мастер создаст метод обработки события (задание делегата с нужной сигнатурой).
После выполнения этих действий (и вставки нашего кода рисования) класс будет выглядеть так.
class MyForm : Form
{
public static void Main()
{
Application.Run (new MyForm());
}
public MyForm()
{
Text = "MyForm";
Width = 700;
Height = 500;
BackColor = Color.LavenderBlush;
Button btnDraw = new Button();
btnDraw.Text = "Click Me";
btnDraw.Size = new Size(80,25);
btnDraw.Location = new Point(5,10);
Controls.Add (btnDraw);
Paint += new PaintEventHandler (MyForm_PaintHandler); // Добавляем делегата
}
void MyForm_PaintHandler (object sender, PaintEventArgs e)
{
Form f = (Form)sender; // Параметр нам не нужен, но интересно, что в нем. Просто убедитесь, что это — ссылка на объект MyForm
Graphics g = e.Graphics;
Brush br = new LinearGradientBrush (new Point(10,10), new Point(300,10),
Color.Violet, Color.Yellow);
g.DrawString ("We are painting", new Font("Arial",28), br, 120, 10);
g.DrawBezier (new Pen(br, 10), new Point(20,250), new Point(5,50),
new Point(300,300), new Point(250,50));
}
}
При запуске компилятор обнаружит ошибку, для исправления которой вам придется добавить директиву using. Нужные пространства имен подскажет (и вставит ссылки) механизм Inellisense (или определите их путем анализа сообщения и MSDN).
Вы заметили, сколько много "новых" (операций захвата памяти new) в этом примере? Как видите, память не жалеют. В Win32-приложениях нас учат запоминать старый инструмент, создавать новый, выбирать его в контекст устройства, использовать, затем восстанавливать старый и уничтожать вновь созданный. Теперь каждый раз, когда надо что-то сделать, все инструменты создаются заново. Это напоминает одноразовую посуду и горы мусора, которые остаются, после того как "новые" попировали. Но, как утверждает Microsoft, это не приводит к потерям — выручает инструмент под названием сборщик мусора (garbage collector).
Система присылает нам контекст устройства HDC (как и в других каркасах, например, MFC) в параметре. Но теперь он спрятан в объекте класса Graphics и передан в функцию с помощью PaintEventArgs.
Как ввести функцию-обработчик сообщения о нажатии кнопки? В конструктор вновь вставьте код, инициирующий мастер вставок: btnDraw.Click +=, и, не торопясь, два раза нажмите Tab.
Событие Click имеется в классе Control, а значит и классе Button (который от него происходит). В коллекцию делегатов события Click (кнопки btnDraw) мы добавили нового делегата со ссылкой на метод btnDraw_Click. Сам метод, реагирующий на событие Click, был создан мастером. В нем мы нарисуем еще одну кривую, соединяющую точки с помощью сплайн-аппроксимации. Здесь важно отметить тот факт, что объект класса Graphics создается локально и уничтожается после использования.
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.