ДЕЛЕГАТЫ, СОБЫТИЯ. DRAG&DROP

16723
знака
0
таблиц
22
изображения

ЛАБОРАТОРНАЯ РАБОТА №5.

ДЕЛЕГАТЫ, СОБЫТИЯ. DRAG&DROP.

Цель

Познакомится с событиями и делегатами. Ознакомиться с работой механизма drag&drop.

Задание

Используя механизм Drag&Drop выбирать тип отрисовываемого объекта и его цвет. Реализовать это все на отдельной форме с вызовом этой формы из основной формы. Передачу сформированного объекта в главную форму осуществлять, используя события. Использовать анонимные функции при решении задачи.

Продолжим тематику машин. Сделаем парковку автосалона, который будем заполнять машинами по желаниям заказчиков (тут в качестве желания будет выступать цвет машины). Нам понадобится 2 формы. Одна будет отображать парковку, вторая – выбор машины и ее настройки.

Разберемся сначала со второй формой. В этой форме потребуется следующий функционал: выбор типа машины и выбор цветов (только основной или еще дополнительный для спортивных машин).

Добавим pictureBox для отображения машины. Добавим groupBox куда добавим 2 Label с вариантами выбора машин, которые мы можем сделать (обычная машина или спорт-версия). Сделаем красивый выбор кузова путем «перетаскивания» элементов. Для этого воспользуемся технологией Drag&Drop.

Для выполнения операций перетаскивания в приложениях Windows необходимо обрабатывать последовательность событий, главным образом события DragEnter, DragLeave и DragDrop. Перетаскивание можно с легкостью организовать при работе со сведениями, доступными через аргументы этих событий.

Рассмотрим это сразу на примере. Начнем с Label с надписью «Car». Все операции перетаскивания начинаются с переноса данных. Функциональные возможности, позволяющие собрать данные при начале перетаскивания, реализуются в методе DoDragDrop. Как и где это применять?. Все начинается, когда мы нажимаем кнопкой мыши на объекте, который хотим перетащить. У каждого элемента формы есть событие, которое срабатывает при нажатии кнопки мыши на него, называется MouseDown. Найдем у Label это событие.

image001.jpg

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

http://dl2.joxi.net/drive/2016/10/19/0018/1806/1230606/06/b62215413c.jpg

Первым параметром, передаваемым в этот метод, является объект, который будет перемещаться. В нашем случае, это будет строка с текстом, размещенным в Label’е. Вторым параметром – возможные результаты операции перетаскивания. В нашем случае это будут операции перемещения и копирования. Результаты можно комбинировать, используя логические операторы.

Теперь на получателе нужно оформить 2 метода, для приема. Но тут возникает проблема. На элементе, который будет принимать перетаскиваемый объект, должно быть свойство AllowDrop. Но его нет у элемента pictureBox. Поэтому сделаем хитрость, поместим pictureBox в panel. У panel задаем значение свойства AllowDrop значением true.

image003.jpg

И задаем методы для 2-х событий: DragEnter и DragDrop.

image004.jpg

Событие DragEnter позволяет убедиться в корректности происходящих действий, в нашем случае, это должен быть текст (строка).

http://dl1.joxi.net/drive/2016/10/19/0018/1806/1230606/06/08bd78d5c9.jpg

Событие DragDrop будет основным, в нем будет реализовываться основная логика. Логика заключается в следующем: в зависимости от переданного текста создать либо обычную машину, либо спортивную версию. Цвет зададим по умолчанию: кузов белый, доп. цвет полосок для спортивных машин – черный. Также, создадим метод, который будет отрисовывать созданную машину. Для этого переменную car сделаем полем класса-формы.

http://dl2.joxi.net/drive/2016/10/19/0018/1806/1230606/06/b2ad457f58.jpg

http://dl1.joxi.net/drive/2016/10/19/0018/1806/1230606/06/d6f3b38315.jpg

Теперь займемся цветами. Зададим 8 возможных цветов. Для разнообразия для этого на форме зададим 8 маленьких панелей, каждую из которых раскрасим в определенный цвет, используя у панелей свойство BackColor. На панели, на которой находится наш pictureBox зададим 2 Label’а, один, куда мы будем перетаскивать цвет для основного кузова, второй, для дополнительного цвета.

Чтобы менять цвета у машины, придется дополнить наши интерфейс ITransport методом получения нового базового цвета и определить его в абстрактном классе Vehicle. А для класса SportCar определить еще метод для получения дополнительного цвета.

http://dl1.joxi.net/drive/2016/10/19/0018/1806/1230606/06/20bed1d226.jpg

http://dl1.joxi.net/drive/2016/10/19/0018/1806/1230606/06/f0295ff5b8.jpg

http://dl2.joxi.net/drive/2016/10/19/0018/1806/1230606/06/f05ad11293.jpg

Для Label основного цвета зададим DragEnter и DragDrop. В качестве передаваемого параметра будет цвет.

http://dl2.joxi.net/drive/2016/10/19/0018/1806/1230606/06/02d0a5ecfe.jpg

Теперь нам надо определить для каждой панели метод MouseDown. Получается 8 раз!! Можно это как-то упростить? По идее, мы задали нужный цвет в свойстве BackColor каждой из панелей. Нам, по сути, надо создать универсальный метод для всех панелей, который бы брал у выбранной панели ее свойство BackColor и передавал в метод DoDragDrop. Теперь проблема, как узнать какую панель выбрали? Но здесь все просто. В каждый вызываемый метод ,как правило, передается 2 параметра: второй – это вызываемое событие, а первый – объект, который его вызвал. Вот он и будет нам нужен. Нам даже все равно что это будет, панель или что-то иное, главное, чтобы он относился к классу элементов формы (класс Control).

http://dl2.joxi.net/drive/2016/10/19/0018/1806/1230606/06/5deb6a88cb.jpg

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

image013.jpg

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

Чтобы видеть, куда мы перетаскиваем, зададим свойство BorderStyle у всех элементов равным FixedSingle, чтобы видеть их границы. У Label свойство AutoSize поставить равным false, чтобы задать нужные размеры для элементов.

Кинем на форму еще 2 кнопки «Добавить» и «Отмена».

На отмену будет простой код: закрытие формы. Сделаем его через анонимную функцию.

http://dl1.joxi.net/drive/2016/10/19/0018/1806/1230606/06/38e95b97f5.jpg

http://dl1.joxi.net/drive/2016/10/19/0018/1806/1230606/06/b08ec86a75.jpg

Воспользуемся нашими классами для отрисовки парковки из предыдущей лабораторной. За одно возьмем оттуда форму отрисовки парковки Уберем кнопки выбора добавления машины и добавим одну кнопку, которая будет вызывать другую форму.

http://dl2.joxi.net/drive/2016/10/20/0018/1806/1230606/06/3185b54828.jpg

Теперь как можно вызвать одну форму из другой? Для этого в классе первой формы создаем объект от второй формы.

http://dl2.joxi.net/drive/2016/10/19/0018/1806/1230606/06/68baccf05f.jpg

Теперь в методе обработки нажатия кнопки «Добавить» инициализируем объект от формы и вызываем у объекта метод Show() иди ShowDialog() для вызова формы. Первый вызывает вторую форму, не блокируя первую. А второй метод блокирует первую форму, пока не закроется вторая.

При выборе первого варианта возникает проблема. После закрытия второй формы, мы должны получить от нее информацию о выбранной машине и добавит ее в гараж. Но как это сделать, если мы не знаем когда закроется эта форма? Со вторым вариантом все просто:

http://dl2.joxi.net/drive/2016/10/19/0018/1806/1230606/06/126ba84939.jpg

Выполнение кода метода продолжится после строки form.ShowDialog(); только когда закроется форма. А для первого варианта придется создать делегат, от него во второй форме событие, функцию добавления к событию метода, и первой форме функцию, которая будет навязываться событию.

Для простоты прям в файле Programm.cs создадим делегат

http://dl1.joxi.net/drive/2016/10/19/0018/1806/1230606/06/498299b0a8.jpg

Затем, во второй форме – событие. И метод добавления к этому событию методов. И вызов события при нажатии кнопки «Добавить»

http://dl2.joxi.net/drive/2016/10/19/0018/1806/1230606/06/30a199307f.jpg

http://dl2.joxi.net/drive/2016/10/19/0018/1806/1230606/06/77e92de01f.jpg

И в первой форме навязываем событие и создаем метод для этого события.

http://dl1.joxi.net/drive/2016/10/19/0018/1806/1230606/06/b3e6c5471d.jpg

Все, теперь сработает и первый вариант вызова формы.

Код первой формы:

public partial class FormSelectCar : Form

{

/// <summary>

/// Переменная-выбранная машина

/// </summary>

ITransport car = null;

/// <summary>

/// Получить машину

/// </summary>

public ITransport getCar { get { return car; } }

/// <summary>

/// Отрисовать машину

/// </summary>

private void DrawCar()

{

if (car != null)

{

Bitmap bmp = new Bitmap(pictureBoxCar.Width, pictureBoxCar.Height);

Graphics gr = Graphics.FromImage(bmp);

car.setPosition(5, 5);

car.drawCar(gr);

pictureBoxCar.Image = bmp;

}

}

/// <summary>

/// Событие

/// </summary>

private event myDel eventAddCar;

/// <summary>

/// Добавление события

/// </summary>

/// <param name="ev"></param>

public void AddEvent(myDel ev)

{

if (eventAddCar == null)

{

eventAddCar = new myDel(ev);

}

else

{

eventAddCar += ev;

}

}

public FormSelectCar()

{

InitializeComponent();

panelBlack.MouseDown += panelColor_MouseDown;

panelGold.MouseDown += panelColor_MouseDown;

panelGray.MouseDown += panelColor_MouseDown;

panelGreen.MouseDown += panelColor_MouseDown;

panelRed.MouseDown += panelColor_MouseDown;

panelWhite.MouseDown += panelColor_MouseDown;

panelYellow.MouseDown += panelColor_MouseDown;

panelBlue.MouseDown += panelColor_MouseDown;

buttonCancel.Click += (object sender, EventArgs e) => { Close(); };

}

/// <summary>

/// Готовимся к перетаскиванию

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

private void labelCar_MouseDown(object sender, MouseEventArgs e)

{

labelCar.DoDragDrop(labelCar.Text,

DragDropEffects.Move | DragDropEffects.Copy);

}

/// <summary>

/// Готовимся к перетаскиванию

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

private void labelSportSedan_MouseDown(object sender, MouseEventArgs e)

{

labelSportCar.DoDragDrop(labelSportCar.Text, DragDropEffects.Move | DragDropEffects.Copy);

}

/// <summary>

/// Проверяем, что мы принимаем (мы не всеядные)

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

private void panelCar_DragEnter(object sender, DragEventArgs e)

{

if (e.Data.GetDataPresent(DataFormats.Text))

e.Effect = DragDropEffects.Copy;

else

e.Effect = DragDropEffects.None;

}

/// <summary>

/// Принимаем то, что перетаскивали

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

private void panelCar_DragDrop(object sender, DragEventArgs e)

{

switch (e.Data.GetData(DataFormats.Text).ToString())

{//случаным образом выбриаем какая машина встанет

case "Car":

car = new Car(100, 4, 500, Color.White);

break;

case "SportCar":

car = new SportCar(100, 4, 500, Color.White, true, true, true, Color.Black);

break;

}

DrawCar();

}

/// <summary>

/// Перетаскиваем цвет с панели

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

private void panelColor_MouseDown(object sender, MouseEventArgs e)

{

(sender as Control).DoDragDrop((sender as Control).BackColor,

DragDropEffects.Move | DragDropEffects.Copy);

}

/// <summary>

/// Готовимся к приему

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

private void labelBaseColor_DragEnter(object sender, DragEventArgs e)

{

if (e.Data.GetDataPresent(typeof(Color)))

e.Effect = DragDropEffects.Copy;

else

e.Effect = DragDropEffects.None;

}

/// <summary>

/// Принимаем

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

private void labelBaseColor_DragDrop(object sender, DragEventArgs e)

{

if (car != null)

{

car.setMainColor((Color)e.Data.GetData(typeof(Color)));

DrawCar();

}

}

/// <summary>

/// Принимаем

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

private void labelDopColor_DragDrop(object sender, DragEventArgs e)

{

if (car != null)

{

if (car is SportCar)

{

(car as SportCar).setDopColor((Color)e.Data.GetData(typeof(Color)));

DrawCar();

}

}

}

/// <summary>

/// Добавление машины

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

private void buttonOk_Click(object sender, EventArgs e)

{

if (eventAddCar != null)

{

eventAddCar(car);

}

Close();

}

}

Код второй формы:

public partial class FormParking : Form

{

/// <summary>

/// Парковка

/// </summary>

Parking parking;

/// <summary>

/// Форма для добавления

/// </summary>

FormSelectCar form;

public FormParking()

{

InitializeComponent();

parking = new Parking(5);

//заполнение listBox

for (int i = 1; i < 6; i++)

{

listBoxLevels.Items.Add("Уровень " + i);

}

listBoxLevels.SelectedIndex = parking.getCurrentLevel;

Draw();

}

/// <summary>

/// Метод для отрисовки уровня парковки

/// </summary>

private void Draw()

{

if (listBoxLevels.SelectedIndex > -1)

{//если выбран один из пуктов в listBox (при старте программы ни один пункт не будет выбран и может возникнуть ошибка, если мы попытаемся обратиться к элементу listBox)

Bitmap bmp = new Bitmap(pictureBoxParking.Width, pictureBoxParking.Height);

Graphics gr = Graphics.FromImage(bmp);

parking.Draw(gr);

pictureBoxParking.Image = bmp;

}

}

/// <summary>

/// Перемещаемся на следующий уровень парковки

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

private void buttonDown_Click(object sender, EventArgs e)

{

parking.LevelDown();

listBoxLevels.SelectedIndex = parking.getCurrentLevel;

Draw();

}

/// <summary>

/// Перемещаемся на нижний уровень парковки

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

private void buttonUp_Click(object sender, EventArgs e)

{

parking.LevelUp();

listBoxLevels.SelectedIndex = parking.getCurrentLevel;

Draw();

}

/// <summary>

/// Вызываем форму добавления машины

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

private void buttonSetCar_Click(object sender, EventArgs e)

{

form = new FormSelectCar();

form.AddEvent(AddCar);

form.Show();

}

/// <summary>

/// Метод добавления машины

/// </summary>

/// <param name="car"></param>

private void AddCar(ITransport car)

{

if (car != null)

{

int place = parking.PutCarInParking(car);

if (place > -1)

{

Draw();

MessageBox.Show("Ваше место: " + place);

}

else

{

MessageBox.Show("Машину не удалось поставить");

}

}

}

/// <summary>

/// Ставим гоночную машину

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

private void buttonSetSportCar_Click(object sender, EventArgs e)

{

ColorDialog dialog = new ColorDialog();

if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)

{

ColorDialog dialogDop = new ColorDialog();

if (dialogDop.ShowDialog() == System.Windows.Forms.DialogResult.OK)

{

var car = new SportCar(100, 4, 1000, dialog.Color, true, true, true, dialogDop.Color);

int place = parking.PutCarInParking(car);

Draw();

MessageBox.Show("Ваше место: " + place);

}

}

}

/// <summary>

/// Забираем машину

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

private void buttonTakeCar_Click(object sender, EventArgs e)

{

if (listBoxLevels.SelectedIndex > -1)

{//Прежде чем забрать машину, надо выбрать с какого уровня будем забирать

string level = listBoxLevels.Items[listBoxLevels.SelectedIndex].ToString();

if (maskedTextBox1.Text != "")

{

ITransport car = parking.GetCarInParking(Convert.ToInt32(maskedTextBox1.Text));

if (car != null)

{//если удалось забрать, то отрисовываем

Bitmap bmp = new Bitmap(pictureBoxTakeCar.Width, pictureBoxTakeCar.Height);

Graphics gr = Graphics.FromImage(bmp);

car.setPosition(5, 5);

car.drawCar(gr);

pictureBoxTakeCar.Image = bmp;

Draw();

}

else

{//иначе сообщаем об этом

MessageBox.Show("Извинте, на этом месте нет машины");

}

}

}

}

}


Варианты:

1. Тигровая Акула – Океан

2. Электровоз – Депо

3. Грузовик – Парковка/Дорога

4. Бомбардировщик – Аэродром/Небо

5. Теплоход – Океан/Причал

6. Бубен – Магазин

7. Линкор – Океан/Причал

8. Горбатый кит - Океан

9. Катер – Океан/Причал

10. Тепловоз – Депо

11. Парусник – Океан/Причал

12. Истребитель – Аэродром/Небо

13. Саксофон – Магазин

14. Автобус – Парковка/Дорога

15. Летающая тарелка – Аэродром/Небо

16. Амурский тигр – Зоопарк/Земля

17. Бриллиант – Магазин

18. Аэробус – Аэродром/Небо

19. Кобра – Террариум/Земля

20. Танк – Гараж/Поле битвы

21. Гитара – Магазин

22. Серый кролик – Зоопарк/Земля

23. Внедорожник – Парковка/Дорога

24. Легкий самолет – Аэродром/Небо

25. Аллигатор – Река/Аквариум

26. БТР – Гараж/Поле битвы

27. Катамаран – Океан/Причал

28. Круизный лайнер – Океан/Причал

29. Тарантул – Террариум/Земля

30. Крейсер – Океан/Причал


Информация о реферате «ДЕЛЕГАТЫ, СОБЫТИЯ. DRAG&DROP»
Раздел: Информатика, программирование
Количество знаков с пробелами: 16723
Количество таблиц: 0
Количество изображений: 22

Похожие материалы

Скачать
39265
0
5

... и оперативного управления процессом обучения, что в свою очередь снижает морально-психологическое напряжение, испытываемое слушателем (студентом) в период сессии. Преимущества и достоинства системы дистанционного обучения, базирующейся на современных телекоммуникационных средствах, становятся очевидными, когда большая часть рутинных операций технологии организации учебного процесса проводятся в ...

0 комментариев


Наверх