Итак, обратите внимание на то, что нам приходится все менять в трех местах, и менять одно и тоже.
//СSharp DotNet Sample Code // ...... // будем рисовать линию private void MenuDrawLine_Click(Object sender, EventArgs e) { menuEdit.Enabled=false; testDraw=true; Cursor=Cursors.Cross; } // будем рисовать полигон private void MenuDrawPoligon_Click(Object sender,EventArgs e) { menuEdit.Enabled=false; testDraw=true; Cursor=Cursors.Cross; } // будем рисовать точку private void MenuDrawPoint_Click(Object sender,EventArgs e) { menuEdit.Enabled=false; testDraw=true; Cursor=Cursors.Cross; } // ......
Можно запутаться. Конечно, функция нужна, ну давайте ее сделаем. Будет называться StartEdit.
//СSharp DotNet Sample Code // будем рисовать линию private void MenuDrawLine_Click(Object sender, EventArgs e) { StartEdit(); } void StartEdit() { menuEdit.Enabled=false; testDraw=true; Cursor=Cursors.Cross; } // будем рисовать полигон private void MenuDrawPoligon_Click(Object sender,EventArgs e) { StartEdit(); } // будем рисовать точку private void MenuDrawPoint_Click(Object sender,EventArgs e) { StartEdit(); }
Теперь лучше исправления всего в одном месте. Думаете таким способом можно идти дальше? Нет, он тупиковый. Мы знаем, что начилось рисование, но не знаем какой тип рисуем. Ведь площадь должна замкнуться, точка и линия разное дело, нарисовать точку это щелкнуть в одном месте, а линия много точек. Значит нам придется завести еще три переменные которые будет говорить о том какой пункт меню выбран. А если типов будет больше например точку можно рассматривать как символ или как окружность что делать ? Заводить 25 переменных типа bool? И в каждой процедуру обработки писать длинный Swith? И не забыть и не перепутать ? Мне кажется это проблематично. Нужен другой выход. Кроме того, мы знаем, что у этих всех процедур рисования есть что-то общее. Это общее механизм рисования.
Начать Продолжить Отменить Зафиксировать
Все начинается естественно с нажатия мышки в начальной позиции а потом по другому, продолжить для линии это еще одна точка, а для точки нечего, можно просто перейти в другое место, нет у нее продолжить. Давайте поступи так. Заведем абстрактный класс и опишем в нем эти методы.
//СSharp DotNet Sample Code // ...... abstract class IMenuDraw { public IMenuDraw(MenuItem menuAccosiate, Form frm) { MenuForm=frm; MenuForm.Cursor=Cursors.Cross; menu=menuAccosiate; menu.Enabled=false; } abstract public void Start(); // первая точка abstract public void Next(); // следующая abstract public void Back(); // отменить последнею virtual public void Finish() // завершить { CanselEdit(); } private void CanselEdit() { menu.Enabled=true; MenuForm.Cursor=Cursors.Default; } Form MenuForm; MenuItem menu; }
Обратите внимание, что управление курсором и пунктом меню уже заложено внутри этого класса. Осталось посмотреть, что нам даст его применение. Давайте порадим от него настоящие классы линий площадей точек.
//СSharp DotNet Sample Code // ...... class DrawPoligon : IMenuDraw { public DrawPoligon(MenuItem menuAccosiate,Form frm):base(menuAccosiate,frm) {} override public void Start() {} public void Break() {} override public void Back() {} override public void Finish() { base.Finish(); } override public void Next() {} } class DrawLines : IMenuDraw { public DrawLines(MenuItem menuAccosiate,Form frm):base(menuAccosiate,frm) {} override public void Start() {} public void Break() {} override public void Finish() { base.Finish(); } override public void Next() {} override public void Back() {} } class DrawPoints : IMenuDraw { public DrawPoints(MenuItem menuAccosiate,Form frm):base(menuAccosiate,frm) {} override public void Start() {} public void Break() {} override public void Finish() { base.Finish(); } override public void Next() {} override public void Back() {} }
Ну и что ? Продолжение следует. Полный код в проекте.