Книга: ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание
Доступ к объекту Graphics вне обработчика Paint
Доступ к объекту Graphics вне обработчика Paint
В некоторых редких случаях может понадобиться доступ к объекту Graphics вне контекста обработчика события Paint. Предположим, например, что нужно перерисовать небольшой круг с центром в точке (х, у), где был выполнен щелчок кнопки мыши. Чтобы получить действительный объект 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);
// Освобождение объектов Graphic, созданных напрямую.
g.Dispose();
}
Эта логика отображает круг за пределами обработчика OnPaint(), но очень важно понимать, что когда выполняется обновление формы, все такие круги стираются! Это разумно, поскольку соответствующая визуализация выполнялась в контексте события MouseDown. Значительно лучшим подходом Является создание в обработчике события MouseDown нового типа Point, который добавляется к некоторой внутренней коллекции (например, List‹T›), и только затем вызывается Invalidate(). Тогда обработчик события Раint может просто "пройти" по коллекции и перерисовать каждый Point.
public partial class MainForm: Form {
// Используется для хранения всех Point.
private List‹Point› myPts = new List‹Point›();
publiс 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("Привет 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. На рис. 20.1 показано окно тестового запуска этого приложения.
Рис 20.1. Простое графическое приложение
Исходный код. Проект BasiсPaintForm размещен в подкаталоге, соответствующем главе 20.
- От полезности, цены и издержек – к внедрению
- Что делать, если при установке принтера появляется сообщение Невозможно завершение операции. Подсистема печати недоступн...
- Безопасная работа с внешними таблицами
- 1.3. Правила подключения к компьютеру внешних устройств
- Безопасность внешних таблиц. Параметр EXTERNAL FILE DIRECTORY
- 9.4. Права доступа к squid
- 8.1.4. Сравнение массивов
- Глава 29 Доступ к канальному уровню
- 10.5. Транзакции и пути доступа меню
- 7. Операция левого внешнего соединения.
- Настройка доступа пользователей к рабочей книге
- 8. Операция правого внешнего соединения.