4

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?

Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219
Alexandr
  • 338
  • 1
  • 4
  • 16
  • 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 Nov 09 '13 at 09:38
  • 1
    @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 Nov 09 '13 at 09:55
  • 1
    @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 Nov 09 '13 at 09:56
  • 1
    @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 Nov 09 '13 at 10:08
  • @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 Nov 09 '13 at 10:14
  • Even is VT source you can see: `amNoWhere, // just for simplified tests, means to ignore the Add/Insert command`. So IMHO `amNoWhere` should be ignored. – kobik Nov 09 '13 at 10:17
  • @kobik, to your previous comment... That's fine :) But for this case you must call `MoveTo` if drop mode is `dmNowhere` and you must also accept drag for "nowhere". Drop mode is a *"place where user dropped"* indicator. If it's empty space, you get `dmNowhere`. Determining that the user dropped node(s) inside an empty space on `DropTargetNode==nil` is a wrong way. – TLama Nov 09 '13 at 10:26

1 Answers1

6

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;
TLama
  • 75,147
  • 17
  • 214
  • 392
  • Shouldn't `dmOnNode` be mapped to `amAddChildLast` also? – kobik Nov 09 '13 at 09:54
  • @kobik, that's not important here. The main point is that `dmNowhere` which indicates drop to an empty space. I think that OP assigned `amNoWhere` to the attach mode, which did no move. – TLama Nov 09 '13 at 09:56
  • 1
    I guess you are right but still I prefer your previous answer where you show all attach modes. +1 – kobik Nov 09 '13 at 10:00