DELPHI实现dbTreeView的节点拖动并更新
目录
【前提说明】
【打开拖动功能】
【启用拖动】
【拖动结束处理】
【拖动功能涉及的自定义函数】
【前提说明】
DELPHI版本:D12
控件类型:dxDBTreeView
【打开拖动功能】
我们先在窗体打开的事件中,将dxDBTreeView控件的拖动功能打开,代码如下:
```
procedure TFrmOrganization.FormShow(Sender: TObject);
begindxDBTreeView1.DragMode := dmAutomatic; // 允许自动拖动
end;
```
【启用拖动】
procedure TFrmOrganization.dxDBTreeView1DragOver(Sender, Source: TObject; X,Y: Integer; State: TDragState; var Accept: Boolean);
varSourceNode, TargetNode: TdxDBTreeNode;
beginAccept := (Source = dxDBTreeView1); // 仅允许同一控件内拖放SourceNode := dxDBTreeView1.Selected as TdxDBTreeNode;TargetNode := dxDBTreeView1.GetNodeAt(X, Y) as TdxDBTreeNode;// 允许拖放到空白处(根节点)if Assigned(SourceNode) thenbeginAccept := True; // 默认允许if Assigned(TargetNode) thenbegin// 额外检查目标合法性Accept := (SourceNode.KeyFieldValue <> TargetNode.KeyFieldValue) and(not IsNodeChild(SourceNode.KeyFieldValue, TargetNode.KeyFieldValue));end;end;end;
【拖动结束处理】
procedure TFrmOrganization.dxDBTreeView1DragDrop(Sender, Source: TObject; X, Y: Integer);
varSourceNode, TargetNode: TdxDBTreeNode;NewParentUID: Variant;
beginSourceNode := dxDBTreeView1.Selected as TdxDBTreeNode;TargetNode := dxDBTreeView1.GetNodeAt(X, Y) as TdxDBTreeNode;if Assigned(SourceNode) thenbegin// 如果拖放到空白处,设置为根节点(ParentUID = Null)NewParentUID := null;if Assigned(TargetNode) thenNewParentUID := TargetNode.KeyFieldValue;// 检查是否允许拖放if (SourceNode.KeyFieldValue <> NewParentUID) and(not IsNodeChild(SourceNode.KeyFieldValue, NewParentUID)) thenbeginUpdateNodeParent(StrToInt(SourceNode.KeyFieldValue),StrToInt(NewParentUID));end;end;end;
【拖动功能涉及的自定义函数】
function TFrmOrganization.IsNodeChild(AParentKey, ACheckKey: Variant): Boolean;
varCurrentKey: Variant;
beginResult := False;if VarIsNull(ACheckKey) then Exit;CurrentKey := ACheckKey;while (not VarIsNull(CurrentKey)) and (CurrentKey <> AParentKey) dobeginCurrentKey := GetParentKeyByChildKey(CurrentKey);end;Result := (CurrentKey = AParentKey);
end;// 辅助函数:根据子节点 Key 获取父节点 Key
function TFrmOrganization.GetParentKeyByChildKey(AChildKey: Variant): Variant;
begin// 示例:通过数据集查询if CDS1.Locate(dxDBTreeView1.KeyField, AChildKey, []) thenResult := CDS1.FieldByName(dxDBTreeView1.ParentField).ValueelseResult := Null;
end;procedure TFrmOrganization.UpdateNodeParent(ASourceKey, ATargetKey: Integer);
varUID:string;
begin
//此处更新数据库,需要与自己程序的字段相对应UID:=IntToStr(ASourceKey);CDS.Close;CDS.CommandText:='update Organization set ParentUID = '''+IntToStr(ATargetKey)+''' where UID = '''+UID+''' ';CDS.Execute;
end;