Рисующее приложение в версии .NET, страница 11

¨  масштабируемые области (scalable regions),

¨  независимые от контекста устройства графические траектории (independent paths).

Многие операции в GDI+ оптимизированы по сравнению с GDI. При рисовании прямой линии следует задать две ее точки, а не одну (последнюю), как было в GDI.

Введите обработку сообщения WM_LBUTTONUP, которое генерируется системой в момент отпускания левой кнопки мыши. В нашем случае это соответствует реакции на событие MouseUp.

private void DrawView_MouseUp(object sender, MouseEventArgs e)

{

if (curLine == null)

return;

Point pt = new Point (e.X, e.Y);

curLine.points.Add (pt);

Graphics g = CreateGraphics();

g.DrawLine (doc.curPen, prevPoint, pt);

prevPoint = pt;

curLine.CalcRect();

doc.UpdateAllViews (this, curLine);

Capture = false;

}

При обновлении рисунка в других видах (см. вызов UpdateAllViews) перерисовываться будут только те линии, прямоугольники которых пересекаются с поврежденным. Это стало возможным благодаря вызову функции CalcRect, вычисляющей прямоугольник линии. Обрамляющие прямоугольники линий учитываются в алгоритме перерисовки вида, реализованном в функции обработки события Paint. Создайте скелет этой функции, дважды щелкнув над этим событием в списке окна свойств формы DrawView.

private void DrawView_Paint(object sender, PaintEventArgs e)

{

Rectangle rClip = e.ClipRectangle, rLine;

rClip.Inflate(1,1); // Предотвращает вырождение прямоугольника, вызванное погрешностями округления

for (int i=0;  i < doc.lineList.Count;  i++)

{

Line line = (Line)doc.lineList[i];

rLine = line.Rect;

rLine.Inflate(1, 1);

if (!rLine.IntersectsWith (rClip))

continue;

line.Draw (e.Graphics);

}

}

Отметьте, что во внутреннюю область ограничивающего прямоугольника какой-либо линии могут входить части других линий. Алгоритм перерисовки пробегает по списку линий рисунка и вызывает метод Draw только для тех линий, которые хоть частично, но попали в поврежденный прямоугольник. Утверждение: «линия частично попала в поврежденный прямоугольник» приблизительно эквивалентно утверждению: «Прямоугольник, ограничивающий линию, пересекается с поврежденным (ClipRectangle)». Учет этого не сильно уменьшит работу по перерисовке, если поврежденный прямоугольник достаточно велик, но в среднем она уменьшится, и нужно отметить, что она точно уменьшится, если новая линия, задающая поврежденный прямоугольник, коротка или лежит в стороне от скопления других линий рисунка. Класс PaintEventArgs содержит данные, необходимые для обработки события Paint и в том числе свойство Graphics, дающее доступ к объекту класса Graphics.

Заметьте, что классы и свойства, обеспечвающие доступ к ним, в .NET Framework довольно часто носят одни и те же имена. Чтобы не потерять логическую нить в вихре событий .NET, следует почаще заглядывать в MSDN, новая версия которой значительно лучше, чем все предыдущие.

В данный момент вы можете запустить приложение (Ctrl+F5) и проверить его функционирование. Рисунок может состоять из произвольного числа линий, которые хранятся в динамической коллекции lineList типа ArrayList. Она используется при восстановлении рисунка в моменты перерисовки окна, которые следуют за такими событиями как: изменение размеров окна вида, сворачивание окна и последующее его разворачивание, потеря фокуса и последующее его восстановление (но только в случае, если оно было заслонено другим окном).

Функция обработки команд меню

В настоящий момент рисунок хранится в памяти и восстанавливается при перерисовке, но он не сохраняется в файле. Очевидно, что это действие должно быть выполнено в ответ на выбор пользователем команды меню File 4Save. Все реакции на выбор команд из меню удобно ввести в класс главного окна. Для этого:

¨  Переведите фокус в окно MainWindow.cs[Design], раскройте меню File и выберите первую команду New,

¨  В окне Properties нажмите кнопку Events, выберите событие Click, введите в строку (справа от него) имя функции обработки MenuItemHandler и нажмите Enter.

Откроется окно с кодами класса, в котором вы увидите каркас функции обработки: