DELPHI实现dbTreeView的节点拖动并更新

目录

【前提说明】

【打开拖动功能】

【启用拖动】

【拖动结束处理】

【拖动功能涉及的自定义函数】


【前提说明】

DELPHI版本:D12
控件类型:dxDBTreeView

【打开拖动功能】


我们先在窗体打开的事件中,将dxDBTreeView控件的拖动功能打开,代码如下:

```


procedure TFrmOrganization.FormShow(Sender: TObject);
begin
   dxDBTreeView1.DragMode := dmAutomatic;  // 允许自动拖动
end;


```

【启用拖动】

procedure TFrmOrganization.dxDBTreeView1DragOver(Sender, Source: TObject; X,
  Y: Integer; State: TDragState; var Accept: Boolean);
var
  SourceNode, TargetNode: TdxDBTreeNode;
begin

    Accept := (Source = dxDBTreeView1);  // 仅允许同一控件内拖放

      SourceNode := dxDBTreeView1.Selected as TdxDBTreeNode;
      TargetNode := dxDBTreeView1.GetNodeAt(X, Y) as TdxDBTreeNode;


      // 允许拖放到空白处(根节点)
      if Assigned(SourceNode) then
      begin
        Accept := True; // 默认允许
        if Assigned(TargetNode) then
        begin
          // 额外检查目标合法性
          Accept := (SourceNode.KeyFieldValue <> TargetNode.KeyFieldValue) and
                    (not IsNodeChild(SourceNode.KeyFieldValue, TargetNode.KeyFieldValue));
        end;
      end;

end;

【拖动结束处理】

procedure TFrmOrganization.dxDBTreeView1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
  SourceNode, TargetNode: TdxDBTreeNode;
  NewParentUID: Variant;
begin
    SourceNode := dxDBTreeView1.Selected as TdxDBTreeNode;
    TargetNode := dxDBTreeView1.GetNodeAt(X, Y) as TdxDBTreeNode;


    if Assigned(SourceNode) then
    begin
      // 如果拖放到空白处,设置为根节点(ParentUID = Null)
      NewParentUID := null;
      if Assigned(TargetNode) then
        NewParentUID := TargetNode.KeyFieldValue;

      // 检查是否允许拖放
      if (SourceNode.KeyFieldValue <> NewParentUID) and
         (not IsNodeChild(SourceNode.KeyFieldValue, NewParentUID)) then
      begin
        UpdateNodeParent(StrToInt(SourceNode.KeyFieldValue),StrToInt(NewParentUID));
      end;
    end;

end;

【拖动功能涉及的自定义函数】

function TFrmOrganization.IsNodeChild(AParentKey, ACheckKey: Variant): Boolean;
var
  CurrentKey: Variant;
begin
  Result := False;
  if VarIsNull(ACheckKey) then Exit;

  CurrentKey := ACheckKey;
  while (not VarIsNull(CurrentKey)) and (CurrentKey <> AParentKey) do
  begin
    CurrentKey := GetParentKeyByChildKey(CurrentKey);
  end;
  Result := (CurrentKey = AParentKey);
end;


// 辅助函数:根据子节点 Key 获取父节点 Key
function TFrmOrganization.GetParentKeyByChildKey(AChildKey: Variant): Variant;
begin
  // 示例:通过数据集查询
  if CDS1.Locate(dxDBTreeView1.KeyField, AChildKey, []) then
    Result := CDS1.FieldByName(dxDBTreeView1.ParentField).Value
  else
    Result := Null;
end;


procedure TFrmOrganization.UpdateNodeParent(ASourceKey, ATargetKey: Integer);
var
   UID:string;
begin
//此处更新数据库,需要与自己程序的字段相对应
    UID:=IntToStr(ASourceKey);

    CDS.Close;
    CDS.CommandText:='update Organization set ParentUID = '''+IntToStr(ATargetKey)+''' where UID = '''+UID+''' ';
    CDS.Execute;
end;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值