Данная статья развивает предыдущие 2 из цикла DBTreeView своими руками и показывает как можно переподчинить узлы. Статьи основаны на книге Д.Осипова Delphi и базы данных c моими небольшими изменениями.
Как видно, переподчинение произошло и в базе данных.
Начали!
Добавляем ещё один компонент запроса
Переподчинение происходит при переносе мышью узлов дерева, технически это Drag&Drop, который успешно поддерживается Delphi. Итак, посмотрим, что у нас есть.
Объявляем DragNode в Private секции
1 |
DragNode:TTreeNode; |
Нам нужно обработать 3 события
On StartDrag
1 2 3 4 |
procedure TMainForm.TreeView1StartDrag(Sender: TObject; var DragObject: TDragObject); begin DragNode:=TreeView1.Selected; end; |
On DragOver
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
procedure TMainForm.TreeView1DragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); var SenderNode:TTReeNode; begin SenderNode:=TreeView1.GetNodeAt(x,y); Accept:=(Assigned(SenderNode)) and not (SenderNode=DragNode) // Не подчинять самому себе and not (SenderNode.HasAsParent(DragNode)) //Родитель не //может быть подчинен ребенку and not (SenderNode=DragNode.Parent) // Не переподчинять тому же узлу end; |
OnDragDrop
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 31 32 33 34 35 36 37 38 39 40 |
procedure TMainForm.TreeView1DragDrop(Sender, Source: TObject; X, Y: Integer); var SenderNode,Node:TTreeNode; begin SenderNode:=TreeView1.GetNodeAt(x,y); if Assigned(SenderNode) and (MessageBox(Application.Handle, PChar('Подчинить '+DragNode.Text+#13+' узлу '+ SenderNode.Text+' ?'), PChar('Перемещение узла'), MB_YESNO+MB_ICONQUESTION)=ID_YES) then begin Screen.Cursor:=crHourgLass; DragNode.MoveTo(SenderNode,naAddChild); // Собственно перенос в дереве // Уведдомляем базу о смене родителя with DMDB.qEditParentKey.Params do begin ParamValues['idParent']:=Integer(SenderNode.Data^); ParamValues['id']:=Integer(DragNode.Data^); end; DMDB.qEditParentKey.ExecSQL; //Пересчитываем абсолютные индексы в базе Node:=TreeView1.Items.GetFirstNode; repeat with DMDB.qEditIndex.Params do begin ParamValues['Index']:=Node.AbsoluteIndex; ParamValues['id']:=Integer(Node.Data^); DMDB.qEditIndex.ExecSQL; end; Node:=Node.GetNext; until not Assigned(Node) ; Screen.Cursor:=crDefault; end; end; |
Запуск механизма DragDrop в событии MouseMove
1 2 3 4 5 6 7 8 9 10 |
procedure TMainForm.TreeView1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var Node:TTreeNode; begin NodeUnderMice:=TreeView1.GetNodeAt(X,Y); if Assigned(NodeUnderMice) and (ssLeft in Shift) then TreeView1.BeginDrag(false,10); end; |