Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > VCL > Drag&Drop в TTreeView


Автор: s-mike 19.04.05, 06:07
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      ComCtrls;
     
    type
      TForm1 = class(TForm)
        TreeView1: TTreeView;
        procedure TreeView1DragDrop(Sender, Source: TObject; X, Y: Integer);
        procedure TreeView1DragOver(Sender, Source: TObject; X, Y: Integer;
          State: TDragState; var Accept: Boolean);
      private
        procedure MoveNode(TargetNode, SourceNode: TTreeNode);
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.MoveNode(TargetNode, SourceNode: TTreeNode);
    var
      NodeTmp: TTreeNode;
      I: Integer;
    begin
      with TreeView1 do
      begin
        // проверяем, является ли целевой элемент предком перетаскиваемого
        NodeTmp := TargetNode.Parent;
        while Assigned(NodeTmp) do
          if NodeTmp = SourceNode then
            Abort
          else
            NodeTmp := NodeTmp.Parent;
     
        // копируем перетаскиваемый элемент в новосозданный
        NodeTmp := Items.AddChild(TargetNode, SourceNode.Text);
        NodeTmp.Data := SourceNode.Data;
     
        for I := 0 to SourceNode.Count - 1 do
          MoveNode(NodeTmp, SourceNode.Item[I]);
     
        Selected := NodeTmp;
        TopItem := NodeTmp.getPrev;
        TargetNode.Expand(True);
      end;
    end;
     
    procedure TForm1.TreeView1DragDrop(Sender, Source: TObject; X, Y: Integer);
    var
      TargetNode, SourceNode: TTreeNode;
    begin
      with TreeView1 do
      begin
        TargetNode := GetNodeAt(X, Y);
        SourceNode := Selected;
     
        if (TargetNode = SourceNode) or (TargetNode = nil) then
        begin
          EndDrag(False);
          Exit;
        end;
        MoveNode(TargetNode, SourceNode);
        SourceNode.Free;
      end;
    end;
     
    procedure TForm1.TreeView1DragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);
    var
      SourceNode, TargetNode, NodeTmp: TTreeNode;
    begin
      if Sender = TreeView1 then
      try
        // скроллинг дерева при перетаскивании
        if Y > TreeView1.Height - 10 then
        begin
          TreeView1.TopItem := TreeView1.TopItem.getNext;
          Sleep(100); // пауза
        end else
          if Y < 10 then
          begin
            TreeView1.TopItem := TreeView1.TopItem.getPrev;
            Sleep(100); // пауза
          end;
     
        TargetNode := TreeView1.GetNodeAt(X, Y);
        SourceNode := TreeView1.Selected;
     
        if (TargetNode = nil) or (TargetNode = SourceNode) then Abort;
     
        Accept := True;
        // проверяем, является ли целевой элемент предком перетаскиваемого
        NodeTmp := TargetNode.Parent;
        while Assigned(NodeTmp) do
          if NodeTmp = SourceNode then
            Abort
          else
            NodeTmp := NodeTmp.Parent;
      except
        Accept := False;
      end;
    end;
     
    end.

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)