Вход/Регистрация
C# для профессионалов. Том II
вернуться

Ватсон Карли

Шрифт:

Это проблема для нашего примера приложения. Мы поместили код рисования в конструктор

Form1
, который вызывается только один раз при запуске приложения, и невозможно вызывать конструктор снова, чтобы перерисовать фигуры, когда это потребуется позже.

В главе 9 при рассмотрении элементов управления нам ничего этого не нужно было знать, так как стандартные элементы управления достаточно развиты и могут правильно перерисовать себя, когда Windows об этом попросит. Это одна из причин, почему при программировании элементов управления вообще не нужно беспокоиться о реальном процессе рисования. Если мы берем на себя ответственность в приложении за рисование на экране, то нам нужно также гарантировать, что приложение будет отвечать правильно, когда Windows попросит перерисовать все или часть окна. В следующем разделе мы изменим пример так, чтобы это было возможно.

Рисование фигур с помощью OnPaint

Если приведенное выше объяснение заставило вас подумать, что рисование своего собственного пользовательского интерфейса будет очень сложной задачей, то не стоит волноваться. Это не так. Были приведены различные детали процесса, для того чтобы вы поняли, с какими проблемами столкнетесь. Но заставить приложение перерисовать себя, когда необходимо, — в действительности легкая задача.

Когда возникает необходимость, Windows уведомляет приложение, что требуется выполнить некоторую перерисовку изображения, инициируя событие

Paint
. Интересно то, что класс
Form
уже реализовал обработчик для этого события, поэтому не нужно создавать свой собственный. Можно воспользоваться этой архитектурой, исходя из факта, что обработчик
Form1
для события
Paint
будет вызывать в процессе обработки виртуальный метод
OnPaint
, передавая в него единственный параметр
PaintEventArgs
. Это означает, что для выполнения рисования необходимо просто переопределить метод
OnPaint
. Мы создадим для этого новый пример, называемый
DrawShapes
. Как и раньше, определяем
DrawShapes
как приложение Windows, генерируемое с помощью Visual Studio.NET, и добавим следующий код класса
Form1
:

protected override void OnPaint(PaintEventArgs e) {

 Graphics dc = e.Graphics;

 Pen BluePen = new Pen(Color.Blue, 3);

 dc.DrawRectangle(BluePen, 0, 0, 50, 50);

 Pen RedPen = new Pen(Color.Red, 2);

 dc.DrawEllipse(RedPen, 0, 50, 80, 60);

 base.OnPaint(e);

}

Отметим, что метод

OnPaint
объявлен как
protected
.
OnPaint
обычно используется внутри класса, поэтому нет необходимости любому другому коду вне класса знать о его существовании.

PaintEventArgs
является производным классом от
EventArgs
, используемого обычно для передачи информации о событиях.
PaintEventArgs
имеет два дополнительных свойства, из которых наиболее важным является экземпляр
Graphics
, уже настроенный и оптимизированный для рисования требуемой части окна. Это означает, что нам не нужно вызывать
CreateGraphics
, чтобы получить контекст устройства в методе
OnPaint
, — он уже существует. Мы вскоре рассмотрим другое дополнительное свойство, оно содержит более подробную информацию о том, какая область окна действительно нуждается в перерисовке.

В данной реализации метода

OnPaint
мы сначала получаем ссылку на объект
Graphics
из
PaintEventArgs
, затем рисуем фигуры так же, как это делалось раньше. В конце вызывается метод
OnPaint
базового класса. Этот шаг является важным. Мы переопределили
OnPaint
для выполнения нашего собственного рисования, но возможно, что Windows должен выполнить свою собственную работу в процессе рисования, и такая работа будет связана с методом
OnPaint
в одном из базовых классов .NET.

Для этого примера может оказаться, что удаление вызова

base.OnPaint
не оказывает никакого влияния на работу, но никогда не пытайтесь удалить вызов. Это может привести к некорректному завершению работы Windows и непредсказуемым результатам.

OnPaint
будет также вызываться, когда приложение впервые запускается и окно приложения выводится в первый раз, поэтому нет необходимости дублировать код рисования в конструкторе, хотя по-прежнему нужно задать здесь цвет фона и все другие свойства формы. Это обычно задается либо добавлением команды явно, либо заданием цвета в окне свойств Visual Studio.NET:

private void InitializeComponent {

 this.components = new System.ComponentModel.Container;

 this.Size = new System.Drawing.Size(300, 300);

 this.Text = "Draw Shapes";

 this.BackColor = Color.White;

}

Выполнение этого кода вначале дает те же результаты, что и в предыдущем примере, за исключением того, что теперь приложение ведет себя правильно, когда окно минимизируется или скрывается его часть.

Использование области вырезания

Пример приложения

DrawShapes
из предыдущего раздела иллюстрирует основные принципы, используемые при рисовании в окне, однако оно не очень эффективно. Причина в том, что оно пытается рисовать в окне все, независимо от того, сколько должно быть перерисовано. Рассмотрим ситуацию, показанную на следующем рисунке. После выполнения приложения
DrawShapes
было открыто другое окно, которое закрыло часть формы
DrawShapes
.

  • Читать дальше
  • 1
  • ...
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: