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

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

 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.

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

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

图片说明

完整的代码 https://download.csdn.net/download/caozhy/10516136