4
votes

A have a tree: ROOT - VirtualStringTree(You don't see it, TVirtualStringTree.RootNode)

  • My Root Node 1
  • My Root Node 2
    • Second node 1
    • Second node 2
    • Second node 3
  • My Root Node 3

I can Drag'n'Drop "My Root Node 3" to any visible node, but I can't return it to defaut position, to the root level of tree.

I try that:

//Part of code from OnDragDrop Event of VirtualStringTree
    if (Sender.DropTargetNode = Sender.RootNode) then
    begin
      for i := 0 to high(Nodes) do
      begin
        LinksTree.MoveTo(Nodes[i], Sender.DropTargetNode, Attachmode, False);
      end;
    end;

I places mouse to nowhere, but nothing happens. In DragOver I accepted drop to root if DropTarget is VST.RootNode.

Anybody knows, how to drop node to VST.RootNode if I drag mouse to empty space of component?

1
suppose you drop "Root node 3" on "Root node 1" and set AttachMode to amInsertBefore it will be moved to the root. add toShowDropmark in PaintOptions to see the drop mark. My logic is as follow: if Mode (TDropMode) is dmAbove I set AttachMode := amInsertBefore; dmOnNode -> amAddChildLast; dmBelow -> amInsertAfter.kobik
@kobik, drop to an empty space is indicated by the dmNowhere drop mode and many examples shows assigning the amNoWhere to the attach mode. And this will be the case, I think, because the call of the MoveTo looks correct. You can move nodes to the RootNode (or nil, which means the same), so the only thing I would suspect is a wrong attach mode.TLama
@TLama, Yes I wanted to mention the amNoWhere but you were faster :) In any case I DO NOT implement amNoWhere becouse I think It's wrong UI behavior to move nodes when there is no visible target nodes.kobik
@kobik, I use amNoWhere value just to initialize the AttachMode local variable. It covers the situation when I forget on a certain drop mode in the case statement and that variable has a "random" value as it's local. Otherwise I also prevent no target node case by accepting OnDragOver event only if there is a target.TLama
@TLama, I see what you mean. I handle the case differently: I simply Exit the event in case Mode==dmNowhere because I have a bit of logic before I actually call MoveTo which should not be used in case of dmNowhere.kobik

1 Answers

6
votes

You haven't shown your code, but basically, you just need to use a proper (attach) Mode parameter for your MoveTo method call for situations, when the (drop) Mode parameter of your OnDragDrop event method equals to dmNowhere, which indicates that the user just dropped node(s) to an empty space of the tree. I assume you're having a code like follows to determine the attach mode in your OnDragDrop event method:

var
  ...
  AttachMode: TVTNodeAttachMode;
begin
  ...
  // the Mode here is a drop mode parameter
  case Mode of
    dmNowhere: AttachMode := amNoWhere; // <- where this stands for no move
    ...
  end;
  ...
end;

If that is so, you can just tell the tree to attach the node e.g. as a last child by changing the attach mode to amAddChildLast if the drop mode will be dmNowhere:

var
  ...
  AttachMode: TVTNodeAttachMode;
begin
  ...
  // the Mode here is a drop mode parameter
  case Mode of
    dmNowhere: AttachMode := amAddChildLast; // <- attach node as a last child
    ...
  end;
  ...
end;