First a clarification, Drag and Drop here refers to drag and drop within the TreeView,
or from the TreeView to another control within the same application. This tutorial does
not cover drag and drop between applications, eg to/from Explorer. That has more to
do with OLE than it does TreeViews.
This example is based on example 10 and there are thus file and folder nodes as well as a root node. Take a look at the "rules" for this TreeView (example 10). These rules must be kept when nodes are dragged.
The OnDragOver event is called when something (on this case a TreeNode) is dragged over a control (a TTreeView). You must indicate if the dragged item may be dropped at the current position.
procedure TForm1.tv_eg5DragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); begin ///////////////////////////////////////// // Decide if drag-drop is to be allowed ///////////////////////////////////////// Accept := false; {Only accept drag and drop from a TTreeView} if( Sender is TTreeView ) then {Only accept from self} if( TTreeView(Sender) = tv_eg5 ) then Accept := true; end;
The OnDragDrop event is called once an item is dropped on the TTreeView. This is a rather long function so a outline of the procedure will help clarify what exactly it does.
procedure TForm1.tv_eg5DragDrop(Sender, Source: TObject; X, Y: Integer); var TargetNode : TTreeNode; SourceNode : TTreeNode; begin ///////////////////////////////////////// // Somthing has just been droped ///////////////////////////////////////// with tv_eg5 do begin {Get the node the item was dropped on} TargetNode := GetNodeAt( X, Y ); {Just to make things a bit easier} SourceNode := Selected; {Make sure somthing was droped onto} if( TargetNode = nil ) then begin EndDrag( false ); Exit; end; {Dropping onto self or onto parent?} if( (TargetNode = Selected) or (TargetNode = Selected.Parent) ) then begin MessageBeep( MB_ICONEXCLAMATION ); ShowMessage( 'Destination node is the same as the source node' ); EndDrag( false ); Exit; end; {No drag-drop of the root allowed} if( SourceNode.Level = 0 ) then begin MessageBeep( MB_ICONEXCLAMATION ); ShowMessage( 'Cant drag/drop the root' ); EndDrag( false ); Exit; end; {Can't drop a parent onto a child} if( IsAParentNode( Selected, TargetNode ) ) then begin MessageBeep( MB_ICONEXCLAMATION ); ShowMessage( 'Cant drop parent onto child' ); EndDrag( false ); Exit; end; {Does a node with this name exists as a child of TargetNde} if( IsDuplicateName( TargetNode.GetFirstChild, SourceNode.Text, true ) ) then begin MessageBeep( MB_ICONEXCLAMATION ); ShowMessage( 'A node with this name already exists' ); EndDrag( false ); Exit; end; ////////////////////////////////////////////////////////////// // Nothing differant up to here. Just the normal drag and // drop checking. Now the code to make sure that enforce // "the rules". Eg books may contain no sub-nodes ////////////////////////////////////////////////////////////// {Use the IsNodeAllowed function to test if the node may be dropped here} if( not IsNodeAllowed( TargetNode, GetNodeType( SourceNode ) ) ) then begin MessageBeep( -1 ); ShowMessage( 'You cant drop this type of node here!' ); EndDrag( false ); Exit; end; {Drag drop was valid so move the nodes} MoveTreeNode( tv_eg5, SourceNode, TargetNode ); {Delete the old node} SourceNode.Delete; {Show the nodes that were just moved} TargetNode.Expand( true ); end; end;
Then...
TreeView to ListView | Get the ListItem the TreeNode was dropped onto. Get the TreeNode that this ListItem is linked to and use it as the TargetNode. |
ListView.TreeView | Get dragged TreeItem, get linked TreeNode use this as SourceNode |
ListView to ListView | Get source and target ListItems, get linked Source and Target TreeNodes. Call function |
I've not actually implemented this, but with the examples in this tutorial you should be able to get this working without too much trouble.
All information on these www pages is copyright (©) 1997 Andre .v.d. Merwe And may not be copied or mirrored without my permission.