814123
2018-07-02 11:57
采纳率: 100%
浏览 1.1k
已采纳

delphi Treeview的节点移动和保存节点位置?

节点移动我用NowNode.MoveTo(NowNode.getPrevSibling,naInsert);可以移动了。
但是下次打开的时候,位置又复原了。
在移动的同时怎么保存它的位置到数据库里呢?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

4条回答 默认 最新

  • blownewbee 2018-07-03 05:40
    已采纳
     unit Unit1;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, DB, ADODB, StdCtrls, ComCtrls;
    
    type
      TForm1 = class(TForm)
        TreeView1: TTreeView;
        Button1: TButton;
        Button2: TButton;
        ADOConnection1: TADOConnection;
        ADOCommand1: TADOCommand;
        ADODataSet1: TADODataSet;
        procedure FormCreate(Sender: TObject);
        procedure LoadSub(id: Integer; node: TTreeNode);
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    
       PMyRc = ^TMyRc;
       TMyRc = Record
         id:Integer;
       end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    
    procedure TForm1.LoadSub(id: Integer; node: TTreeNode);
    var
      node1 : TTreeNode;
      ADOCommand2 : TADOCommand;
      ADODataSet2 : TADODataSet;
      p:PMyRc;
    begin
      ADOCommand2 := TADOCommand.Create(Self);
      ADOCommand2.Connection := ADOConnection1;
      ADOCommand2.CommandText := 'select * from table1 where parentid =' + IntToStr(id) + ' order by [order]';
      ADODataSet2 := TADODataSet.Create(Self);
      ADODataSet2.Recordset := ADOCommand2.Execute();
      while not(ADODataSet2.Eof) do
      begin
        node1 := TreeView1.Items.AddChild(node, ADODataSet2['text']);
        New(p);
        p.id:=StrToInt(ADODataSet2['id']);
        node1.Data := p;
        LoadSub(ADODataSet2['id'], node1);
        ADODataSet2.Next();
      end;
    end;
    
    procedure TForm1.FormCreate(Sender: TObject);
    var
      node : TTreeNode;
      p:PMyRc;
    begin
      ADOConnection1.Open();
      ADOCommand1.CommandText := 'select * from table1 where parentid = -1 order by [order]';
      ADODataSet1.Recordset := ADOCommand1.Execute();
      while not(ADODataSet1.Eof) do
      begin
        node := TreeView1.Items.AddChild(nil, ADODataSet1['text']);
        New(p);
        p.id:=StrToInt(ADODataSet1['id']);
        node.Data := p;
        LoadSub(ADODataSet1['id'], node);
        ADODataSet1.Next();
      end;
    end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    var
      Curr : TTreeNode;
      Pre : TTreeNode;
    begin
      Curr := TreeView1.Selected;
      Pre := Curr.getPrevSibling();
      if (Pre <> nil) then
        Curr.MoveTo(Pre, naInsert);
      TreeView1.SetFocus();
    end;
    
    procedure TForm1.Button2Click(Sender: TObject);
    var
      Curr : TTreeNode;
      Pre : TTreeNode;
    begin
      Curr := TreeView1.Selected;
      Pre := Curr.getNextSibling();
      if (Pre <> nil) then
        Curr.MoveTo(Pre, naAdd);
      TreeView1.SetFocus();
    end;
    
    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    var
      i : Integer;
      p:PMyRc;
    begin
      for i := 0 to TreeView1.Items.Count - 1 do
      begin
         p := pmyrc(TreeView1.Items[i].Data);
         ADOCommand1.CommandText := 'update table1 set [order] = ' + IntToStr(i) + ' where id =' + IntToStr(p^.id);
         ADOCommand1.Execute();
      end;
    end;
    
    end.
    
    
    点赞 评论
  • blownewbee 2018-07-02 12:31

    位置有两个含义,一个是层次的位置,也就是从某个节点搬动到和它的父节点、子节点或者兄弟节点,堂兄弟节点平级的位置。
    另一个是在相同的层次中,调整和它的兄弟节点的顺序。

    前者,你需要存储每个节点的父节点的id,以及当前节点的id
    后者,你需要一个额外的排序字段,加载treeview的时候读取,并且按照从小到大的顺序加载。如果要移动,就交换它和某个节点的排序的值

    点赞 评论
  • blownewbee 2018-07-03 05:41

    图片说明

    点赞 评论
  • blownewbee 2018-07-03 05:43
    点赞 评论

相关推荐 更多相似问题