Ключевым обстоятельством, которое должно быть вам абсолютно понятным, если вы используете подключение к функциям Paint, является то, что вы не в состоянии контролировать, когда именно будут вызываться эти функции. Вы можете сделать это принудительно, объявив область экрана недействительной, но не имеете никакой возможности контролировать внешние факторы, которые могут инициировать запросы перерисовки экрана. Поэтому крайне важно, чтобы операции перерисовки осуществлялись как можно быстрее и с малыми накладными расходами. Если перерисовка экрана осуществляется очень медленно, то будет создаваться впечатление, что ваше приложение работает в замедленном режиме.
//Кисти, которые мы хотим кэшировать, чтобы избавить себя
//от необходимости все время создавать их и уничтожать
System.Drawing.Brush m_brushBlue;
System.Drawing.Brush m_brushYellow;
//Ради интереса подсчитаем, сколько раз осуществлялся вызов
int m_paintCount;
//-----------------------------------------------------------------------------
//Мы перекрываем обработчики событий Paint наших базовых классов. Это означает,
//что каждый раз, когда форма вызывается для перерисовки самой себя, будет
//вызываться эта функция.
//-----------------------------------------------------------------------------
protected override void OnPaint(PaintEventArgs e) {
//ВАЖНО: Вызвать базовый класс и дать ему возможность
//выполнить всю необходимую работу по рисованию
base.OnPaint(e);
//Увеличить на 1 значение счетчика вызовов
m_paintCount = m_paintCount + 1;
//------------------------------------------------------------------------
//Важно:
//Вместо того чтобы создавать объект Graphics, мы получаем его на время
//данного вызова. Это означает, что освобождать память путем вызова
//метода .Dispose объекта - не наша забота
//------------------------------------------------------------------------
System.Drawing.Graphics myGfx;
myGfx = e.Graphics;
//-------------------------------------------------------------------
//Поскольку эту операцию рисования необходимо выполнить быстро,
//кэшируем кисти, чтобы избавить себя от необходимости создавать их и
//уничтожать при каждом вызове
//-------------------------------------------------------------------
if (m_brushBlue == null) {
m_brushBlue = new System.Drawing.SolidBrush(System.Drawing.Color.Blue);
}
if (m_brushYellow == null) {
m_brushYellow = new System.Drawing.SolidBrush(System.Drawing.Color.Yellow);
}
//-------------------
//Выполнить рисование
//-------------------
myGfx.FillRectangle(m_brushBlue, 2, 2, 100, 100);
myGfx.DrawString("PaintCount: " + m_paintCount.ToString, this.Font, mbrushYellow, 3, 3);
//Выход: Объекты, для которых мы должны были бы вызывать метод
//.Dispose, отсутствуют.
}