加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Delphi树视图在节点之间拖放

发布时间:2020-12-15 09:08:59 所属栏目:大数据 来源:网络整理
导读:我希望允许用户按照自己喜欢的方式安排treeView的节点,但是我遇到了很多问题.例如: 在我做了一些拖放后,树视图停止响应,我 必须杀死该应用程序.如果我开始拖动并放弃(按 取消,或从我选择它的地方放弃它)应用程序挂起……我什么也做不了 如果用户想要重新排
我希望允许用户按照自己喜欢的方式安排treeView的节点,但是我遇到了很多问题.例如:

>在我做了一些拖放后,树视图停止响应,我
必须杀死该应用程序.如果我开始拖动并放弃(按
取消,或从我选择它的地方放弃它)应用程序挂起……我什么也做不了
>如果用户想要重新排列3个子节点的顺序
相同的主节点,他不能像在其他应用程序中那样做.为什么?
是否有任何方法允许用户在BETWEEN中删除他的节点
2个其他节点? Delphi似乎只允许用户点头
另一个.

这不好.我想要像这张照片中的行为

因此Node3的目的地应该在Node1和Node2之间.当然,节点的ON TOP应该是可用的,但是这个BETWEEN NODES功能也应该可用.

到目前为止我的代码是:

procedure TForm3.FormCreate(Sender: TObject);
begin
  tv.FullExpand;
end;

procedure TForm3.tvDragDrop(Sender,Source: TObject; X,Y: Integer);
var
  TargetNode,SourceNode : TTreeNode;
begin
  with TV do
  begin
    TargetNode := GetNodeAt(X,Y); // Get target node
    SourceNode := Selected;
    if (TargetNode = nil) then
    begin
      EndDrag(False);
      Exit;
    end;
    MoveNode(TargetNode,SourceNode);
    SourceNode.Free;
  end;
end;

procedure TForm3.tvDragOver(Sender,Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
  if (Sender = TV) then // If TRUE than accept the draged item
  begin
    Accept := True;
  end;
end;
procedure TForm3.tvEndDrag(Sender,Target: TObject; X,Y: Integer);
begin
  TV.Repaint;
end;

procedure TForm3.tvMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X,Y: Integer);
begin
  tv.BeginDrag(false,-1);
end;

Procedure TForm3.MoveNode(TargetNode,SourceNode : TTreeNode);
var
  nodeTmp : TTreeNode;
  i : Integer;
begin
  with TV do
  begin
    nodeTmp := Items.AddChild(TargetNode,SourceNode.Text);
    for i := 0 to SourceNode.Count -1 do
    begin
      MoveNode(nodeTmp,SourceNode.Item[i]);
    end;
  end;
end;

当然电视是TTreeView.

解决方法

首先,扔掉你目前拥有的所有代码.它有太多的缺陷值得讨论.

这需要的最小代码如下:

procedure TMyForm.TreeView1DragDrop(Sender,Y: Integer);
var
  Src,Dst: TTreeNode;
begin
  Src := TreeView1.Selected;
  Dst := TreeView1.GetNodeAt(X,Y);
  Src.MoveTo(Dst,naAdd);
end;

procedure TMyForm.TreeView1DragOver(Sender,Y: Integer;
  State: TDragState; var Accept: Boolean);
var
  Src,Y);
  Accept := Assigned(Dst) and (Src<>Dst);
end;

您需要将树形视图的DragMode设置为dmAutomatic.而且您还需要将两个事件连接到OnDragDrop和OnDragOver.

如果您希望在drop中实现不同的逻辑以处理作为兄弟(之前或之后)的添加,或者作为子项添加,则为MoveTo的第二个参数传递不同的值.

可能性列于此处:

type
  TNodeAttachMode = (naAdd,naAddFirst,naAddChild,naAddChildFirst,naInsert);

这些选项在documentation中描述.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读