我希望允许用户按照自己喜欢的方式安排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, Source: TObject; X, 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, Source: TObject; X, Y: Integer); var Src, Dst: TTreeNode; begin Src := TreeView1.Selected; Dst := TreeView1.GetNodeAt(X,Y); Src.MoveTo(Dst, naAdd); end; procedure TMyForm.TreeView1DragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); var Src, Dst: TTreeNode; begin Src := TreeView1.Selected; Dst := TreeView1.GetNodeAt(X,Y); Accept := Assigned(Dst) and (Src<>Dst); end;
您需要将树形视图的DragMode设置为dmAutomatic.而且您还需要将两个事件连接到OnDragDrop和OnDragOver.
如果您希望在drop中实现不同的逻辑以处理作为兄弟(之前或之后)的添加,或者作为子项添加,则为MoveTo的第二个参数传递不同的值.
可能性列于此处:
type TNodeAttachMode = (naAdd, naAddFirst, naAddChild, naAddChildFirst, naInsert);
这些选项在documentation中描述.