//----------------------------------------------------------------
//Создать новую кисть, которую мы собираемся использовать для фона
//----------------------------------------------------------------
m_RectangleBrush = new System.Drawing.SolidBrush(m_RectangleColor);
//------------------------------------------------------------
//Сообщить операционной системе, что наш элемент управления
//должен быть перерисован, как только представится возможность
//------------------------------------------------------------
this.Invalidate();
}
//----------------------------------------------------------------
//Ради интереса подсчитаем, сколько раз осуществлялась перерисовка
//----------------------------------------------------------------
int m_paintCount;
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) {
//--------------------------------------------
//ВАЖНО: Вызвать базовый класс и позволить ему
//выполнить работу по рисованию
//--------------------------------------------
base.OnPaint(e);
//Увеличить на единицу значение счетчика вызовов
m_paintCount = m_paintCount + 1;
//-------------------------------------------------------------------
//Важно:
//Вместо того чтобы создавать объект Graphics, мы получаем его
//на время данного вызова. Это означает, что освобождать память путем
//вызова метода .Dispose() объекта - не наша забота
//-------------------------------------------------------------------
System.Drawing.Graphics myGfx;
myGfx = e.Graphics;
//Нарисовать прямоугольник
myGfx.FillRectangle(m_RectangleBrush, 0, 0, this.Width,this.Height);
//Нарисовать текст
myGfx.DrawString("Button! Paint: " + m_paintCount.ToString(), this.Parent.Font, m_TextBrush, 0, 0);
} //конец функции
} //конец класса
Листинг 11.10. Код, который должен быть помещен в форму для создания экземпляра пользовательского элемента управления
//--------------------------------------------------------------
//Этот код будет подключен в качестве нашего обработчика событий
//--------------------------------------------------------------
private void CallWhenButtonTurningBlue(object sender, System.EventArgs e) {
System.Windows.Forms.MessageBox.Show("Button is about to turn blue!");
}
//Наша новая кнопка
myButton m_newControl;
//----------------------------------------------
//Эта функция подключается для обработки событий
//щелчка на кнопке Button1
//----------------------------------------------
private void button1_Click(object sender, System.EventArgs e) {
//----------------------------------------------
//Для простоты мы допускаем существование только
//одного экземпляра элемента управления.
//----------------------------------------------
if (m_newControl != null) {
return;
}
//Создать экземпляр нашей кнопки
m_newControl = new myButton();
//Указать ему его местоположение внутри родительского объекта
m_newControl.Bounds = new Rectangle(10, 10, 150, 40);
//-------------------------------
//Присоединить обработчик событий
//-------------------------------
m_newControl.EventButtonTurningBlue += new System.EventHandler(this.CallWhenButtonTurningBlue);
//Добавить его в список элементов управления данной формы.
//Это сделает его видимым
this.Controls.Add(m_newControl);
}
Где рисовать — на экране или вне экрана?
Создание привлекательной графики — в равной степени и искусство, и ремесло; под этим подразумевается, что одинаково важная роль принадлежит как используемым методикам, так и планированию. Для того чтобы нарисовать на экране одиночный прямоугольник или одиночный фрагмент текста, требуется очень мало времени. Рисование же сложной диаграммы или игрового поля на лету в видимой области экрана, скорее всего, заставят пользователя дожидаться появления результатов в течение некоторого времени. Рассмотрим случай сложной диаграммы, на рисование которой уходит 1,5 секунды. Эта длительность заметно превышает порог человеческого восприятия, и глаз человека в состоянии различить довольно много событий, которые могут произойти на протяжении такого временного промежутка. Если рисование диаграммы состоит из стадий рисования фонового изображения, вычерчивания и сопровождения надписями осей диаграммы, размещения точек, соответствующих фактическим данным, и генерации таблицы ключей, в которой каждый набор данных идентифицируется определенным цветом, то процесс построения диаграммы, происходящий на глазах у пользователя, будет представлять собой весьма неприглядную картину. Результат будет еще более плачевным, если получаемая графика предназначена для динамической игры; в этом случае пользователь столкнется с мерцанием экрана, сопровождающим перерисовку элементов игры при их перемещениях на экране.