各位大虾,我想把TreeView控件的某一父节点下的所有子节点移动到其他子节点或父节点中,但是我只能移动父节点一个节点,我应该如何做呢?非常感谢大家!
代码如下:
procedure TAFX_dw_basic.TreeView1DragDrop(Sender, Source: TObject; X,
Y: Integer);
var
mynode:TTreenode;
begin
try
Screen.Cursor := crHourGlass;
if drag_flag=false then exit;
d_node:=Treeview1.DropTarget; //拖放的目的节点
if d_node=nil then exit;
//如果源节点和目的节点相同,则什么也不做
if pdw(d_node.Data)^.dwid=getupid(drag_start) then exit;
if MessageDLG('确定要移动吗?',mtConfirmation, [mbYes, mbNo], 0) = mrYes then
begin
if d_node.HasChildren then
drag_end:=next_id(pdw(d_node.Data)^.dwid)
else
drag_end:=pdw(d_node.Data)^.dwid+'001';
ClientDataSet_dw.Locate('dw_id',drag_start,[loCaseInsensitive]);
ClientDataSet_dw.Edit;
ClientDataSet_dw.FieldByName('dw_id').value:=drag_end;
new(p_dw);
p_dw^.dwid:=drag_end;
p_dw^.dwname:=gloabnode.Text;
mynode:=Treeview1.Items.AddChild(d_node,p_dw^.dwname);
mynode.Data:=p_dw;
gloabnode.Delete;
UpdateDWID(drag_end,drag_start);
end;
finally
drag_flag:=false;
Screen.Cursor := crDefault;
end;
end;
///////////////////////////////////
变量:drag_flag:boolean; //拖拽标志
drag_start,drag_end:string[21]; //拖拽值
d_node:TTreenode; //拖拽node
代码如下:
procedure TAFX_dw_basic.TreeView1DragDrop(Sender, Source: TObject; X,
Y: Integer);
var
mynode:TTreenode;
begin
try
Screen.Cursor := crHourGlass;
if drag_flag=false then exit;
d_node:=Treeview1.DropTarget; //拖放的目的节点
if d_node=nil then exit;
//如果源节点和目的节点相同,则什么也不做
if pdw(d_node.Data)^.dwid=getupid(drag_start) then exit;
if MessageDLG('确定要移动吗?',mtConfirmation, [mbYes, mbNo], 0) = mrYes then
begin
if d_node.HasChildren then
drag_end:=next_id(pdw(d_node.Data)^.dwid)
else
drag_end:=pdw(d_node.Data)^.dwid+'001';
ClientDataSet_dw.Locate('dw_id',drag_start,[loCaseInsensitive]);
ClientDataSet_dw.Edit;
ClientDataSet_dw.FieldByName('dw_id').value:=drag_end;
new(p_dw);
p_dw^.dwid:=drag_end;
p_dw^.dwname:=gloabnode.Text;
mynode:=Treeview1.Items.AddChild(d_node,p_dw^.dwname);
mynode.Data:=p_dw;
gloabnode.Delete;
UpdateDWID(drag_end,drag_start);
end;
finally
drag_flag:=false;
Screen.Cursor := crDefault;
end;
end;
///////////////////////////////////
变量:drag_flag:boolean; //拖拽标志
drag_start,drag_end:string[21]; //拖拽值
d_node:TTreenode; //拖拽node
给你点建议
判断能否Drop不应该像你那样,应该在DragOver事件中判断
procedure TForm1.TreeView1DragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
这个ACcept就表示能否接受拖放目标。给个简单的例子你参考。procedure TForm1.TreeView1DragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
function IsChild(TNode,SNode:TTreeNode):boolean;
var
TempNode: TTreeNode;
begin
if TNode = SNode then
begin
Result := True;
exit;
end;
tempNode := Tnode.Parent;
while Assigned(TempNode) do
begin
if TempNode = sNode then
begin
Result := true;
exit;
end;
tempNode := tempnode.Parent;
end;
Result := False;
end;
var
TargetNode: TTreeNode;
begin
TargetNode := TreeView1.DropTarget;
if (Sender = TreeView1) and Assigned(TargetNode) then
begin
//检查目标是否合法
if IsChild(TargetNode,treeview1.Selected) or (TreeView1.Selected.Parent = TargetNode) then
accept := false
else
Accept := true;
end { (Sender = TreeView1) and Assigned(TargetNode) }end;
procedure TForm1.TreeView1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
AttachMode: TNodeAttachMode;
begin
with TreeView1 do
begin
if Not Assigned(Selected) then Exit;
if Assigned(DropTarget.Data) then //如果是目标是叶节点
AttachMode := naInsert //插入
else
AttachMode := naAddChild; //否则加为子节点
Selected.MoveTo(DropTarget, AttachMode);
Selected.MakeVisible;
end;
end;
找到当前节点的节点号,然后在找到当前节点的兄弟几点的节点号,记录当前节点的partent节点,然后重新填加。
其实要是有数据库就好了,可以重新生成文本在load 就可以了
State: TDragState; var Accept: Boolean);
var
targetnode,sourcenode: TTreenode;
begin
targetnode := tvArea.getnodeat(x,y);
if (Source = Sender) and (targetnode <> nil) then //保证移动在TreeView上,且目标节点不为空
begin
Accept := true;
sourcenode := tvArea.selected;
//以下代码防止用户将一个选项拖到其子项上(它会随着选项一起移动,导致死循环)
while (targetnode.parent <> nil) and (targetnode <> sourcenode) do
targetnode := targetnode.parent;
if (targetnode = sourcenode) then Accept := false;
end
else Accept := false;
end;procedure TFrmArea.tvAreaDragDrop(Sender, Source: TObject; X, Y: Integer);
var
targetnode,sourcenode: TTreenode;
SqlStr: String;
targetNodeInf: PAreaNodeInf; //目的节点
sourcenodeInf : PAreaNodeInf; //目标节点
begin targetnode := tvArea.getnodeat(x,y); //获得目的节点
sourcenode := tvArea.selected; //获得目标节点
New(targetNodeInf);
New(sourcenodeInf); sourcenodeInf:= sourcenode.Data;
targetNodeInf := targetNode.Data; //修改数据库中当前节点的父节点号parent_id,使其等目标节点标识号;
SqlStr:='update Area set Area_UC= '''+targetNodeInf.Area_CC+''''+
' Where Area_CC ='''+sourcenodeInf.Area_CC+''''; with DMArea.adocmdArea do
begin
CommandText := SqlStr;
try
Execute;
except
on E :exception do
begin
Showmessage('修改地域出错!');
Exit;
end;
end;
end; tvArea.items.beginupdate; //禁用TreeView重绘操作
try
copynodeunder(tvArea,sourcenode,targetnode); //启动移动过程
tvArea.selected := targetnode;
finally
tvArea.items.endupdate; //重新设置
end;
end;
////copy树
procedure TFrmArea.CopyNodeUnder(Treeview: TTreeview; Sourcenode,
TargetNode: TTreeNode; i: integer);
var
NewNode: Ttreenode;
j: integer;
begin
NewNode:=treeview.items.addchildfirst(targetnode,''); //建立目标项
NewNode.assign(SourceNode); //复制源项属性
for j:=sourcenode.count-1 downto 0 do //递归调用,按倒序移动其所有子项
CopyNodeUnder(treeview,sourcenode.item[j],newnode);
//treeview.items.delete(sourcenode); //删除源项
end;