[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 602
  • Last Modified:

drag / drop from treeview to listview

Hello all experts!

I hope anyone can help me with this difficult question, i have try for a long time and nothing works.

Saint10
0
saint10
Asked:
saint10
  • 9
  • 9
  • 3
1 Solution
 
LischkeCommented:
Hi Saint10,

well, it doesn't look very complicated to do drag'n drop this way. I think the main problem you have to solve is to decide how this should happen. E.g. drag only top nodes which become list items and their children become subitems of the list items (and if so what should happen in the case where there are several child nodes) or do you just want to move the selected node and its children as new items into the listview etc. I think you see what I'm trying to say here.

Ciao, Mike
0
 
saint10Author Commented:
If i have the item like this

+ Network / Computers
   \\COMPUTER1
   \\COMPUTER2
   \\COMPUTER3
+ Network / Printers
   \\PRINTER1
   \\PRINTER2
   \\PRINTER3

i want to drag only subitems, but if i drag
'Network / Computers' i want to add all subitems into listview

Saint10
0
 
saint10Author Commented:
If i have the item like this

+ Network / Computers
   \\COMPUTER1
   \\COMPUTER2
   \\COMPUTER3
+ Network / Printers
   \\PRINTER1
   \\PRINTER2
   \\PRINTER3

i want to drag only subitems, but if i drag
'Network / Computers' i want to add all subitems into listview

Saint10
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LischkeCommented:
Ok, let's formulate this a bit different. If you drag a node without children then only this node should added as item into the listview and if you drag a node with children then not the node but its children should be added to the listview (still as normal items, not subitems). Is this so far correct?

If yes (and I assume you have enough knowledge about drag'n drop) then a solution would look like:

procedure TMainForm.ListView1DragDrop(Sender, Source: TObject; X, Y: Integer);

var
  Node: TTreeNode;
  Item: TListItem;
  I: Integer;

begin
  if Source = NetworkTree then
    with Sender as TListView do
    begin
      Node := NetworkTree.Selected;
      if Node.HasChildren then
      begin
        for I := 0 to Node.Count - 1 do
        begin
          Item := Items.Add;
          Item.Caption := Node[I].Text;
        end;
      end
      else
      begin
        Item := Items.Add;
        Item.Caption := Node.Text;
      end;
    end;
end;

Ciao, Mike
0
 
LischkeCommented:
Don't press your browser's refresh button but use the Reload Question link on this page to reload it. Otherwise your last post will be reposted.

Ciao, Mike
0
 
saint10Author Commented:
i have no knowledge about drag and drop

can you show me all events?

Saint10
0
 
liferilyCommented:
I was about to answer my first question but I wasn't fast enough!
Have you considered the tree nodes children's children etc...
0
 
LischkeCommented:
:-)) I think this is my last question for today. I'm going home now and am back in the office on monday, so you have plenty of time to find another question to answer. Although, you can still contribute to this discussion. Perhaps your comment will be picked as answer or a dummy question is opened just to give you some points for your work...


Saint10,

to make the dragging work you need to start it at an appropriate time point. Usually, this is automatically done when the user holds down the left mouse button and moves the mouse a bit. Set the DragMode property of the treeview to dmAutomatic. This will start the drag operation when a node is clicked in the tree and the mouse button is held down while moving the mouse over to the listview.

The listview (and any other control for that matter) need to indicate that they can and want to accept a drag operation. For this you have to assign an OnDragOver event handler (select the listview, go to the object inspector and double click the event OnDragOver. Write this text then:

procedure TMainForm.ListView1DragOver(Sender, Source: TObject; X,
  Y: Integer; State: TDragState; var Accept: Boolean);
begin
  Accept := True;
end;

Now go back to the object inspector and double click the OnDragDrop event. Insert the text I gave you already in the handler:

procedure TMainForm.ListView1DragDrop(Sender, Source: TObject; X, Y: Integer);

var
  Node: TTreeNode;
  Item: TListItem;
  I: Integer;

begin
  if Source = NetworkTree then
    with Sender as TListView do
    begin
      Node := NetworkTree.Selected;
      if Node.HasChildren then
      begin
        for I := 0 to Node.Count - 1 do
        begin
          Item := Items.Add;
          Item.Caption := Node[I].Text;
        end;
      end
      else
      begin
        Item := Items.Add;
        Item.Caption := Node.Text;
      end;
    end;
end;

That's all to make the drag'drop operation working. Quite easy huh?

Ciao, Mike
0
 
liferilyCommented:
Bye Mike

I'm just leaving work too

I don't want to be pedantic but you may want to be more restrictive on the accept...

procedure TForm1.ListView1DragOver(....................);
begin
  Accept := false;

  // If you want to restrict the drop to tree then check for tree
  If (Source is TTreeView) then
  begin
    // If you want to restrict the drop to a particular tree then check for a particular tree
    If TTreeView(Source).Name = 'TreeView1' then Accept := true;
  end;
end;

cheers

jr
0
 
saint10Author Commented:
Can i use multivalues?

Saint10
0
 
LischkeCommented:
jr, you are right. One has, of course, to restrict the acceptance to certain cases. But I didn't want to complicate the code with stuff which wasn't important for the particular task.

Saint10, if you don't want to use third-party components like my TreeNT (see www.lischke-online.de) then you have no possibility to use multiselection with the treeview (I hope that's what you meant with "multivalues"). On the other hand I showed you already how to pass more than one node along, so I'm not sure what you also need.

Ciao, Mike
0
 
saint10Author Commented:
Can i use your excellent TreeNT component and use multiselect and drag?
0
 
LischkeCommented:
Of course you can. Build an outer loop around the the node copy to access all selected nodes:

procedure TMainForm.ListView1DragDrop(Sender, Source: TObject; X, Y: Integer);

var
  Node: TTreeNTNode;
  Item: TListItem;
  I: Integer;

begin
  if Source = NetworkTree then
    with Sender as TListView do
    begin
      Node := NetworkTree.Items.GetFirstSelectedNode;
      while Assigned(Node) do
        if Node.HasChildren then
        begin
          for I := 0 to Node.Count - 1 do
          begin
            Item := Items.Add;
            Item.Caption := Node[I].Text;
          end;
        end
        else
        begin
          Item := Items.Add;
          Item.Caption := Node.Text;
        end;
        Node := Node.GetNextSelected;
      end;
    end;
end;

Ciao, Mike
0
 
saint10Author Commented:
when i drag over listview , the listview will not stop add
------------------------------------------------------------

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ComCtrls, TreeNT;

type
  TForm1 = class(TForm)
    TreeNT1: TTreeNT;
    ListView1: TListView;
    procedure ListView1DragDrop(Sender, Source: TObject; X, Y: Integer);
    procedure ListView1DragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);
    procedure TreeNT1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.ListView1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
Node: TTreeNTNode;
Item: TListItem;
I: Integer;
begin
if Source = TreeNT1 then
with Sender as TListView do
begin
Node := TreeNT1.Items.GetFirstSelectedNode;
while Assigned(Node) do
if Node.HasChildren then
begin
for I := 0 to Node.Count - 1 do
begin
Item := Items.Add;
Item.Caption := Node[I].Text;
end;
end
else
begin
Item := Items.Add;
Item.Caption := Node.Text;
end;
Node := Node.GetNextSelected;
end;
end;

procedure TForm1.ListView1DragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
if Source is TTreeView then
 Accept:=true;
end;

procedure TForm1.TreeNT1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
APoint:TPoint;
begin
APoint.x:=x;
APoint.y:=y;
if TreeNT1.GetNodeAt(x,y)<>nil then
TreeNT1.begindrag(false);

end;

end.

What's wrong?
0
 
LischkeCommented:
Try this code:

begin
  if Source = TreeNT1 then
    with Sender as TListView do
    begin
      Node := TreeNT1.Items.GetFirstSelectedNode;
      while Assigned(Node) do
      begin
        if Node.HasChildren then
        begin
          for I := 0 to Node.Count - 1 do
          begin
            Item := Items.Add;
            Item.Caption := Node[I].Text;
          end;
        end
        else
        begin
          Item := Items.Add;
          Item.Caption := Node.Text;
        end;
        Node := Node.GetNextSelected;
      end;
    end;
end;

There was a begin missing after the while ... line and you have fixed that wrongly, I think. I hope this is finally what you need :-)

Ciao, Mike
0
 
saint10Author Commented:
when i drag over listview , the listview will not stop add
------------------------------------------------------------

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ComCtrls, TreeNT;

type
  TForm1 = class(TForm)
    TreeNT1: TTreeNT;
    ListView1: TListView;
    procedure ListView1DragDrop(Sender, Source: TObject; X, Y: Integer);
    procedure ListView1DragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);
    procedure TreeNT1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.ListView1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
Node: TTreeNTNode;
Item: TListItem;
I: Integer;
begin
if Source = TreeNT1 then
with Sender as TListView do
begin
Node := TreeNT1.Items.GetFirstSelectedNode;
while Assigned(Node) do
if Node.HasChildren then
begin
for I := 0 to Node.Count - 1 do
begin
Item := Items.Add;
Item.Caption := Node[I].Text;
end;
end
else
begin
Item := Items.Add;
Item.Caption := Node.Text;
end;
Node := Node.GetNextSelected;
end;
end;

procedure TForm1.ListView1DragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
if Source is TTreeView then
 Accept:=true;
end;

procedure TForm1.TreeNT1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
APoint:TPoint;
begin
APoint.x:=x;
APoint.y:=y;
if TreeNT1.GetNodeAt(x,y)<>nil then
TreeNT1.begindrag(false);

end;

end.

What's wrong?
0
 
LischkeCommented:
Don't press the refresh button of your browse here at E-E. There's a link in the upper right corner to reload the page.

Ciao, Mike
0
 
saint10Author Commented:
i forgot "refresh button" , thanks this all works very fine and i'am now very happy man. I raise the points up to 200, you own that.

Saint10
0
 
LischkeCommented:
Thank you very much (also for the A grading). Whenever you need further help, just ask.

Ciao, Mike

PS: If you are interested in a totally new tree implementation then watch out the next few weeks. I'm just finishing my virtual treeview, a high capacity and extremly fast implementation. I'll upload it to all major Delphi sites as well as to my home page.
0
 
saint10Author Commented:
Thanks
0
 
liferilyCommented:
I've just got into work

It appears there has been quite a discussion between the two of you

I might be a little busy for a while but I'll read the comments and see how it developed.
0

Featured Post

Prep for the ITIL® Foundation Certification Exam

December’s Course of the Month is now available! Enroll to learn ITIL® Foundation best practices for delivering IT services effectively and efficiently.

  • 9
  • 9
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now