Получение объекта Graphics вне обработчика события Paint

В некоторых редких случаях может понадобиться доступ к объекту Graphics за пределами контекста обработчика события Paint. Например, предположим, что вы хотите нарисовать маленький кружок в позиции (x, y), где был выполнен щелчок кнопкой мыши. Один подход к получению действительного объекта Graphics из контекста обработчика события MouseDown состоит в вызове статического метода Graphics.FromHwnd (). Из опыта работы с Win32 вам должно быть известно, что HWND — это структура данных, представляющая некоторое окно Win32. На платформе. NET унаследованное свойство Handle извлекает лежащий в основе HWND, который может применяться в качестве параметра для Graphics.FromHwnd ():

private void MainForm_MouseDown(object sender, MouseEventArgs e)

{

// Получить объект Graphics через Hwnd.

Graphics g = Graphics.FromHwnd(this.Handle);

// Теперь нарисовать кружок 10*10 в месте щелчка кнопкой мыши.

g.FillEllipse(Brushes.Firebrick, e.X, e.Y, 10, 10);

// Освободить все объекты Graphics, созданные непосредственно.

g.Dispose();

}

Хотя эта логика визуализирует кружок вне обработчика события OnPaint (), очень важно понимать, что когда форма делается недействительной (и потому должна быть перерисована), каждый из кружков будет стерт! Это имеет смысл, учитывая, что визуализация случается только в контексте события MouseDown. Намного лучший подход состоит в том, чтобы позволить обработчику MouseDown создать новый экземпляр Point, который затем добавляется к внутренней коллекции (вроде List < T >), с последующим вызовом Invalidate (). В этот момент обработчик событий Paint может просто выполнить итерацию по коллекции и нарисовать каждый Point:

public partial class MainForm: Form

{

// Используется для запоминания всех точек.

private List<Point> myPts = new List<Point>();

public MainForm()

{

...

this.MouseDown += new MouseEventHandler(MainForm_MouseDown);

}

private void MainForm_MouseDown(object sender, MouseEventArgs e)

{

// Добавить в коллекцию точек.

myPts.Add(new Point(e.X, e.Y));

Invalidate();

}

private void MainForm_Paint(object sender, PaintEventArgs e)

{

Graphics g = e.Graphics;

g.DrawString("Hello GDI+", new Font("Times New Roman", 20),

new SolidBrush(Color.Black), 0, 0);

foreach(Point p in myPts)

g.FillEllipse(Brushes.Firebrick, p.X, p.Y, 10, 10);

}

}

При таком подходе визуализированные кружки навсегда останутся на поверхности окна, поскольку вся графическая визуализация происходит в событии Paint. На рис.1 показан результат тестового запуска этого начального приложения GDI+.

Рис.1. Простое приложение рисования


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: