Технология "перетаскивания" - Drag and Drop в Delphi



Сегодня рассмотрим такую интересную вещь, как Drug and Drop - "Перетащи и отпусти". Возможно, вы уже слышали о данной технологии, которая позволяет перемещать объекты зажатием на них мыши. Например, в проводнике Windows мы с лёгкостью можем зажать курсором файл, перетащить его и скинуть в какой-либо дирректории. Или, как второй пример, можно привести панель задач windows. Мы можем перенести на неё какую-либо иконку и она останется закреплена на ней. Вот эти действия и представляют собой технологию Drug and Drop. Давайте рассмотрим, как она работает.

ТЕОРИЯ.

Для начала нужно сказать, что почти у всех визуальных компонентов (кнопки, панели, list-box'ы, etc) имеются описанные события, благодаря которым можно реализовать данную технологию. Рассмотрим эти события:

1) OnStartDrag:

Инициатором события выступает объект-источик, генерируется в начале операции перетаскивания. Событие имеет 2 параметра:

1) Объект приемник (грубо говоря, проводя аналогию, объект-приемник в случае с проводником windows является дирректория, куда мы скидываем объект, т.е. эта дирректория ПРИНИМАЕТ зажатый нами объект.) - DragObject: TDragObject

2) Объект источник (Объект, который мы перетаскиваем) - Sender: TObject

2) OnDragOver:

Событие генерируется объектом-приемником, возникается в тот момент, когда объект под курсором мыши двигается над объектом-приемником. Событие имеет 6 параметров:

1) Sender: TObject - Ссылка на объект-приемник

2) Source: TObject - Ссылка на объект-источник

3,4) X,Y: Integer - Координаты текущего указателя мыши

5) State (dsDragEnter - Указатель появился над приёмником; dsDragLeave - Указатель убран с поверхности объекта-приемника; dsDragMove - Указатель движется над приёмником)

6) Accept: Boolean - Признак подтверждения операции перемещения (если операция прошла успешно - TRUE, иначе - FALSE)

3) OnDragDrop:

Событие генерирует элемент-приемник, возникает оно при отпускании мыши. Если параметр Accept, полученный в событии OnDragOver имеет значение True, то элемент-источник успешно ляжет на элемент-приемник. Событие имеет 4 параметра:

1,2) Sender, Source: TObject - описаны выше;

2,3) X, Y: integer - так же аналогичны событиям, описанным в событии DragOver.

4) OnEndDrag - Вне зависимости от того, приняла ли переменная Accept значение True (можно передать элемент) или осталась ли она False (запрет на передачу элементов) - сгенерируется это событие, инициатором выступает объект-источник. Параметры (Sender, Target: TObject; X,Y: integer;) полносью аналогичный описанным выше. Стоит сказать, что в данном случае параметр Target - объект-приемник.

События представлены именно в том порядке, в котром они будут генерироваться во время операции перетаскивания.

ПРАКТИКА.

Наконец-то закончили с теорией, приступим уже к кодингу. Первым делом, нужно выбрать, что будем перетаскивать. В моём случае - это будут 2 ListBox'а (перемещать, разумеется, будем строки в них).

Форма:



Ну и не менее важное занятие - настроить свойства. Их, для Drag and Drop, 2:

1) DragKind (dkDrag или dkLock):

dkDrag - разрешает Drag and Drop; dkLock - блокирует Drag and Drop.

2) DragMode (dmManual или dmAutomatic) - режим работы Drag and Drop. Говоря про Automatic режим - тут тоже нужно описывать свойства, но не все, а 2. При этом программа сама будет генерировать остальные. В нашем случае нужно выбрать dmManual, т.к. нам нужно запоминать строки и передавать их от компонента-источника к компоненту-приемнику.

У каждого из List-box'ов пишем почти аналогичный код в следующих свойствах:

OnMouseMove:

begin
if (listbox1.ItemIndex <> -1) and ( ssLeft in Shift ) then //Если нажата левая кнопка мыши (ssLeft in Shift) и выделенна строка, то
listbox1.BeginDrag(False,8); //Начинаем операцию Drag (перетаскивание)
end;


Прописываем переменную i в раздел приватных переменных (private) и продолжаем.

OnStartDrag:

begin
i:= listbox1.ItemIndex; // Запоминаем номер у выделенной строки
end;


OnDragOver:

begin
Accept:= (i <> -1) and (Sender<> Source); // Accept = true, если переменная i запомнила выделенную строку и объект-приеник не является объектом-источником.
end;


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

OnDragDrop:

var
  строка: string;
begin
{Передаём строку из списка Sourse в список Sender}
строка:= listBox1.Items.Strings[Index]; // ложим в переменную нужную строку
listbox2.Items.Add(строка); // передаём ей в объект-приемник (в нашем случае второй listbox)
listBox1.Items.Delete(I); // удаляем перемещённую строку из первого источника
end;


OnEndDrag:

begin
I:= -1; // Выставим переменной ложное значение по завершению операции
end;


Проверим?

1) Захватили объект (строку) с компонента-источника (1-ый listbox) и потащали объект (обратите внимание на курсор):



2) Навели объект на компонент-приёмник (второй объект):



3) Отпустили объект, он удалился из listbox1 и появился в listbox2:



Спасибо за внимание.
Теги:
объект, события, Событие, Объект, TObject, можем, Ссылка, приемник, можно, курсором, приемником, объектом, Sender, имеет, генерируется, рассмотрим, технологию, дирректория, windows, является
Добавлено: 24 Февраля 2015 19:39:13 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...