Шаг 174 - Меню и классы еще дальше

Итак в прошлом шаге мы создали классы на основе абстрактного класса, чем это может помочь в работе с меню? Мы уже вроде как определили круг проблем. Осталось только эти классы применить, будем применять. Заведем переменную типа родителя класса.

// CSharp Sample Code
// ......
// Выход из программы пункт Exit
private void MenuExit_Click(Object sender, EventArgs e)
{
	Application.Exit();
} 
	
// будем рисовать линию
private void MenuDrawLine_Click(Object sender, EventArgs e)
{}
	
// будем рисовать полигон
private void MenuDrawPoligon_Click(Object sender,EventArgs e)
{}
	
// будем рисовать точку
private void MenuDrawPoint_Click(Object sender,EventArgs e)
{}
	
// мышка нажата
protected override void OnMouseDown(MouseEventArgs e) 
{}

// клавиша нажата
protected override void OnKeyPress(KeyPressEventArgs e)
{}

IMenuDraw idraw=null;
MenuItem menuEdit;
}
}

Обратите внимание на то, я убрал всякие там переменные, которые говорят, что режим редактирование наступил, правильно если idraw не NULL, то значит был выбран пункт меню, а еще я удалит функцию StartEdit, потому что все необходимое сделает класс. Давайте будем применять наши классы.

// CSharp sample Code
// ......
// Выход из программы пункт Exit
private void MenuExit_Click(Object sender, EventArgs e)
{
	Application.Exit();
} 
	
// будем рисовать линию
private void MenuDrawLine_Click(Object sender, EventArgs e)
{
	idraw= new DrawLines(menuEdit,this);		
}
	
// будем рисовать полигон
private void MenuDrawPoligon_Click(Object sender,EventArgs e)
{
	idraw = new DrawPoligon(menuEdit,this);
}
	
// будем рисовать точку
private void MenuDrawPoint_Click(Object sender,EventArgs e)
{
	idraw = new DrawPoints(menuEdit,this);
}
	
// мышка нажата
protected override void OnMouseDown(MouseEventArgs e) 
{}

// клавиша нажата
protected override void OnKeyPress(KeyPressEventArgs e)
{
	idraw.Break();
	idraw = null;
}

IMenuDraw idraw=null;
MenuItem menuEdit;
}
}

Обратите внимание, что при выборе пункта меню создается объект соответствующего типа, а дальше просто используются его функции например при редактировании нажатие клавиш вызывает прерывание операции, курсор возвращается в обычное состояние, меню разблокируеться. Я там немного код поменял в проекте в плане того, что писал функцию Break в базовом классе а в остальных удалил, все подробности к черту, ой в проекте. Так вот смотрите как все становиться круто. Если мы хотим что бы по нажатию клавиши Enter объект записался в куда-то а по ESC просто прекратилось его создание то нам нужно сделать это в одном месте в проекте.

// CSharp sample code
// клавиша нажата
protected override  void OnKeyPress(KeyPressEventArgs e)
{
// проверка что идет редактирование
	if (idraw!=null)
	{
		switch(e.KeyChar)
		{
		case (char) 23:	// нажата ESС Прервать
			idraw.Break();
			idraw = null;
			break;
		case (char) 13: // нажата ENTER Потвердить
			idraw.Finish();
			idraw=null;
			break;
		}
	}
}

	IMenuDraw idraw=null;
	MenuItem menuEdit;
}
}

Обратите внимание на смещение акцентов, мы не думаем о том как это работает в классе, мы не думаем какой класс, мы заботимся только о том что нужно. Потом позже мы пойдем в реализацию класса и там напишем, а может и Ваш товаришь будет писать реализацию. А если мы захотим по нажатию Back сделать отмену последний точки? Нет проблем, пишите абстрактную функцию в абстрактном классе, потом в этот то же кож заносите реакцию и только после реализуете в конкретном классе. Обратите внимание нам не нужно проверять какой пункт меню был выбран, заводить 100 переменных типа bool. Даже то что редактирование началось мы узнаем по наличию самого объекта. Нет его idraw==null значит меню не выбрано. Еще момент всякие там курсоры и меню реализовано в базовом абстрактном классе. Нам даже думать об этом больше не надо.

Данное решение очень удобно. Скажем Вы захотите сделать, чтобы пользователь мог рисовать готовые фигуры, например квадрат, круг. Становить совсем просто, достаточно описать пункт меню и описать класс. Но не надо нечего править в коде ответственном за события , все будет работать само сабой. Есть всего одно место где Вы можете ошибиться, это реализация класса, но оно локализовано, оно известно. Еще раз создав логику для одного класса как он будет реагировать на события, отладив ее дальше можно применять ее с другим классам. Вы расширяете функциональность программы с минимальным количеством кода. Надеюсь что идею Вы поняли и оценили. И еще один момент, мы в классе формы оставили только логику, реализацию конкретных механизмов вынесли в другой класс.


Загрузить проект | Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем - 01.11.2001