如何解决TTreeView节点批量的上移和下移操作

时间:2022-03-30 14:47:55
实现:定义一个记录,一个指针指向该记录,同时定义一个指针数组,在加载树节点时,为数组赋值(顺序赋值),同时将节点的信息存放到记录中,在操作时你可以根据树当前选中节点的绝对顺序来取得相应节点的信息(记录中),要移动时你只需要找出要移到的节点的位置,然后再改变相应数组的信息,最后移动节点,同时要改变相应数组的元素值

9 个解决方案

#1


看的很晕?
到底是移节点还是移指针数组里的指针?

ttreenode.data可以存放数据指针,无须指针数组了吧?

#2


引用 1 楼 sz_haitao 的回复:
看的很晕?
到底是移节点还是移指针数组里的指针?

ttreenode.data可以存放数据指针,无须指针数组了吧?

就是批量移动节点  
procedure TprysdaQDK_CKZMForm.actQDDownExecute(Sender: TObject);
var
  tmpNode: TTreeNode;
  tn: Ttreenode;
begin
  if (QD_NR_TV.Selected = nil) or (QD_NR_TV.Selected.Level = 0)  then
    Exit;
  tn := QD_NR_TV.Items.Item[QD_NR_TV.Items.count-1] ;
  while tn <> nil do
  begin
    if tn.Selected = True then
    begin
      tmpNode :=tn.getNextSibling;
      if tmpNode = nil then
        Exit;
      tmpNode.MoveTo(tn,naInsert);
    end;
    tn := tn.GetPrev;
  end;
  BZ := True;
end;
移动单个节点没问题,多选就不可以了。

#3


procedure TprysdaQDK_CKZMForm.actQDDownExecute(Sender: TObject);
var
  tmpNode: TTreeNode;
  tn: Ttreenode;
begin
  if (QD_NR_TV.Selected = nil) or (QD_NR_TV.Selected.Level = 0)  then
    Exit;
  tn := QD_NR_TV.Items.Item[QD_NR_TV.Items.count-1] ;
  while tn <> nil do
  begin
    if tn.Selected = True then
    begin
      tmpNode :=tn.getNextSibling;
      if tmpNode = nil then
        Exit;
      tmpNode.MoveTo(tn,naInsert);
    end;
    tn := tn.GetPrev;
  end;
  BZ := True;
end;

#4


如何解决TTreeView节点批量的上移和下移操作求大神指导下啊!!

#5


想把多选的节点,全部与它的弟弟调换位置??

#6


引用 5 楼 sz_haitao 的回复:
想把多选的节点,全部与它的弟弟调换位置??

不管按shift或者ctrl多选,选中多个节点,按自定义的上移或下移按钮,可以同时上移,下移。

#7


多个节点,层次各有不同,也移动?
假设有简单树如下:动作为上移
a
 1
 2 选中
 3
 4 选中
4与3换了位置后,下一个循环又到4了,因为它位于第3个位置了。。。

另外,注意移动一次后,多选的状态会不会自动消失

#8


引用 7 楼 sz_haitao 的回复:
多个节点,层次各有不同,也移动?
假设有简单树如下:动作为上移
a
 1
 2 选中
 3
 4 选中
4与3换了位置后,下一个循环又到4了,因为它位于第3个位置了。。。

另外,注意移动一次后,多选的状态会不会自动消失

type
  TRec = record
    ndtxt: string;
    state : Boolean;
  end;
  TPRec = ^TRec;

procedure TprysdaQDK_CKZMForm.actQDDownExecute(Sender: TObject);
var
  tmpNode: TTreeNode;
  tn: Ttreenode;
  nd:  Array Of TRec;
  tmnd :TRec;
  i: integer;
begin
  if (QD_NR_TV.Selected = nil) or (QD_NR_TV.Selected.Level = 0)  then
    Exit;
   ////////移动定额////////
   SetLength(nd,QD_NR_TV.Items.count-1);
   //GetMem(nd, SizeOf(TRec));
   tn := QD_NR_TV.Items.GetFirstNode;
   i := 0;
   while tn <> nil do
   begin
    nd[i].ndtxt:=tn.Text;
    nd[i].state:=tn.Selected;
    Inc(i);
    tn := tn.GetNext;
  end;

  for i:= QD_NR_TV.Items.count-1 downto 0 do
  begin
    if nd[i].state = True  then
    begin
      tmnd.ndtxt:=nd[i].ndtxt;
      tmnd.state:=nd[i].state;
      nd[i].ndtxt:=nd[i+1].ndtxt;
      nd[i].state:=nd[i+1].state;
      nd[i+1].ndtxt:=tmnd.ndtxt;
      nd[i+1].state:=tmnd.state;
    end;
  end;
   tn := QD_NR_TV.Items.GetFirstNode;
   i := 0;
   while tn <> nil do
   begin
    tn.Text:=nd[i].ndtxt;
    tn.Selected:=nd[i].state;
    Inc(i);
    tn := tn.GetNext;
  end;

我又重新写了,但是报错。

#9


引用 7 楼 sz_haitao 的回复:
多个节点,层次各有不同,也移动?
假设有简单树如下:动作为上移
a
 1
 2 选中
 3
 4 选中
4与3换了位置后,下一个循环又到4了,因为它位于第3个位置了。。。

另外,注意移动一次后,多选的状态会不会自动消失

procedure TprysdaQDK_CKZMForm.actQDDownExecute(Sender: TObject);
var
  tmpNode: TTreeNode;
  tn: Ttreenode;
  nod: array of TTreeNode;
  I, J: integer;
begin
  if (QD_NR_TV.Selected = nil) or (QD_NR_TV.Selected.Level = 0)  then
    Exit;
   ////////移动定额////////

  J := QD_NR_TV.SelectionCount;
  tn := QD_NR_TV.Items.GetFirstNode;
  SetLength(nod,J);
  I:=0;
  while tn <> nil do
  begin
    if tn.Selected = True then
    begin
      nod[I]:=tn;
      Inc(I);
    end;
    tn := tn.GetNext;
  end;
  for  I:=J-1 downto 0 do
  begin
    tmpNode:=nod[I].getNextSibling;
    if tmpNode =nil then
      Exit;
     tmpNode.MoveTo(nod[I],naInsert)
  end;
  QD_NR_TV.Select(nod);
  BZ := True;
end;

这样就可以了额,不够还是很感谢了。

#1


看的很晕?
到底是移节点还是移指针数组里的指针?

ttreenode.data可以存放数据指针,无须指针数组了吧?

#2


引用 1 楼 sz_haitao 的回复:
看的很晕?
到底是移节点还是移指针数组里的指针?

ttreenode.data可以存放数据指针,无须指针数组了吧?

就是批量移动节点  
procedure TprysdaQDK_CKZMForm.actQDDownExecute(Sender: TObject);
var
  tmpNode: TTreeNode;
  tn: Ttreenode;
begin
  if (QD_NR_TV.Selected = nil) or (QD_NR_TV.Selected.Level = 0)  then
    Exit;
  tn := QD_NR_TV.Items.Item[QD_NR_TV.Items.count-1] ;
  while tn <> nil do
  begin
    if tn.Selected = True then
    begin
      tmpNode :=tn.getNextSibling;
      if tmpNode = nil then
        Exit;
      tmpNode.MoveTo(tn,naInsert);
    end;
    tn := tn.GetPrev;
  end;
  BZ := True;
end;
移动单个节点没问题,多选就不可以了。

#3


procedure TprysdaQDK_CKZMForm.actQDDownExecute(Sender: TObject);
var
  tmpNode: TTreeNode;
  tn: Ttreenode;
begin
  if (QD_NR_TV.Selected = nil) or (QD_NR_TV.Selected.Level = 0)  then
    Exit;
  tn := QD_NR_TV.Items.Item[QD_NR_TV.Items.count-1] ;
  while tn <> nil do
  begin
    if tn.Selected = True then
    begin
      tmpNode :=tn.getNextSibling;
      if tmpNode = nil then
        Exit;
      tmpNode.MoveTo(tn,naInsert);
    end;
    tn := tn.GetPrev;
  end;
  BZ := True;
end;

#4


如何解决TTreeView节点批量的上移和下移操作求大神指导下啊!!

#5


想把多选的节点,全部与它的弟弟调换位置??

#6


引用 5 楼 sz_haitao 的回复:
想把多选的节点,全部与它的弟弟调换位置??

不管按shift或者ctrl多选,选中多个节点,按自定义的上移或下移按钮,可以同时上移,下移。

#7


多个节点,层次各有不同,也移动?
假设有简单树如下:动作为上移
a
 1
 2 选中
 3
 4 选中
4与3换了位置后,下一个循环又到4了,因为它位于第3个位置了。。。

另外,注意移动一次后,多选的状态会不会自动消失

#8


引用 7 楼 sz_haitao 的回复:
多个节点,层次各有不同,也移动?
假设有简单树如下:动作为上移
a
 1
 2 选中
 3
 4 选中
4与3换了位置后,下一个循环又到4了,因为它位于第3个位置了。。。

另外,注意移动一次后,多选的状态会不会自动消失

type
  TRec = record
    ndtxt: string;
    state : Boolean;
  end;
  TPRec = ^TRec;

procedure TprysdaQDK_CKZMForm.actQDDownExecute(Sender: TObject);
var
  tmpNode: TTreeNode;
  tn: Ttreenode;
  nd:  Array Of TRec;
  tmnd :TRec;
  i: integer;
begin
  if (QD_NR_TV.Selected = nil) or (QD_NR_TV.Selected.Level = 0)  then
    Exit;
   ////////移动定额////////
   SetLength(nd,QD_NR_TV.Items.count-1);
   //GetMem(nd, SizeOf(TRec));
   tn := QD_NR_TV.Items.GetFirstNode;
   i := 0;
   while tn <> nil do
   begin
    nd[i].ndtxt:=tn.Text;
    nd[i].state:=tn.Selected;
    Inc(i);
    tn := tn.GetNext;
  end;

  for i:= QD_NR_TV.Items.count-1 downto 0 do
  begin
    if nd[i].state = True  then
    begin
      tmnd.ndtxt:=nd[i].ndtxt;
      tmnd.state:=nd[i].state;
      nd[i].ndtxt:=nd[i+1].ndtxt;
      nd[i].state:=nd[i+1].state;
      nd[i+1].ndtxt:=tmnd.ndtxt;
      nd[i+1].state:=tmnd.state;
    end;
  end;
   tn := QD_NR_TV.Items.GetFirstNode;
   i := 0;
   while tn <> nil do
   begin
    tn.Text:=nd[i].ndtxt;
    tn.Selected:=nd[i].state;
    Inc(i);
    tn := tn.GetNext;
  end;

我又重新写了,但是报错。

#9


引用 7 楼 sz_haitao 的回复:
多个节点,层次各有不同,也移动?
假设有简单树如下:动作为上移
a
 1
 2 选中
 3
 4 选中
4与3换了位置后,下一个循环又到4了,因为它位于第3个位置了。。。

另外,注意移动一次后,多选的状态会不会自动消失

procedure TprysdaQDK_CKZMForm.actQDDownExecute(Sender: TObject);
var
  tmpNode: TTreeNode;
  tn: Ttreenode;
  nod: array of TTreeNode;
  I, J: integer;
begin
  if (QD_NR_TV.Selected = nil) or (QD_NR_TV.Selected.Level = 0)  then
    Exit;
   ////////移动定额////////

  J := QD_NR_TV.SelectionCount;
  tn := QD_NR_TV.Items.GetFirstNode;
  SetLength(nod,J);
  I:=0;
  while tn <> nil do
  begin
    if tn.Selected = True then
    begin
      nod[I]:=tn;
      Inc(I);
    end;
    tn := tn.GetNext;
  end;
  for  I:=J-1 downto 0 do
  begin
    tmpNode:=nod[I].getNextSibling;
    if tmpNode =nil then
      Exit;
     tmpNode.MoveTo(nod[I],naInsert)
  end;
  QD_NR_TV.Select(nod);
  BZ := True;
end;

这样就可以了额,不够还是很感谢了。