Dragcursor in Drag&Drop in TAdvTreeView

I have a working Drag & Drop in a TAdvTreeView, using BeforDropNode and AfterDropnode. The only thing I am missing is a way to change the Dragcursor when a dragged node is over a node that it can't be dropped upon.
I tried this, but that did not work:

procedure TForm1.TVBeforeDropNode(Sender: TObject; AFromNode, AToNode: TAdvTreeViewVirtualNode;
  var ACanDrop: Boolean);
  ACanDrop := ((AToNode <> NIL) and
              (AToNode.Extended) and
              ((AToNode.Children = 0) or (not AToNode.Node.Nodes[0].Extended)));
  if not ACanDrop then TV.DragCursor := crNoDrop else TV.DragCursor := crDrag;

The obvious question is: how can I achieve this?


You can use the following code to achieve this:

  TAdvTreeViewOpen = class(TAdvTreeView);

procedure TForm1.DoCustomDragOver(Sender, Source: TObject; Point: TPointF;
  var Accept: Boolean);
  n: TAdvTreeViewVirtualNode;
  n := AdvTreeView1.XYToNode(Point.X, Point.Y);
  if Assigned(n) and (n.Level = 0) then
    Accept := False
    Accept := True;

procedure TForm1.FormCreate(Sender: TObject);
  AdvTreeView1.Interaction.DragDropMode := tdmMove;
  TAdvTreeViewOpen(AdvTreeView1).OnCustomDragOver := DoCustomDragOver;

Pieter Scheldeman2019-11-05 13:54:42

Hi, I tried this and it works great. Thank you!


I experience something strange when Dropping the Node and using the AfterDropNode event.
I expected the AFromNode to be the Node that is Dropped and the AToNode to be the Node that is dropped upon. When I drop, the AToNode is correct, but the AFromNode seems to miss some parameters. I use non-virtual nodes, so I have to use this construction if I want to know which Node is dropped upon which node by using their DBKeys:

procedure TFormItems.TVAfterDropNode(Sender: TObject; AFromNode, AToNode: TAdvTreeViewVirtualNode);
    ShowMessage('from=' + AFromNode.Node.DBKey + '  to=' + AToNode.Node.DBKey);

But in this case the AFromNode does not have a node. It is nil. So I don't have a DBKey either, which gives me an acces-violation.
I use TAdvTreeView

In the OnAfterDropNode, the node are already switched. You can use the OnBeforeDropNode and the AFromNode and AToNode are still the original ones before switching.

But does the OnBeforeDropNode event occur only once, just like the OnAfterDropNode event? I want to use this event to do some housekeeping after the drop. But I need something from the original Node. I can do that in the OnBeforeDropNode event as well, but I must be sure it only occurs once. Now I only use it to determine if ACanDrop is True.

It only occurs once.