Delphi TreeView树型框节点拖拽停靠、按条件开始拖拽

简介:

OnDragOver处理是否允许放下:

01.procedure TMainForm.TreeViewDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);   
02.var  
03.  TargetNode, SourceNode: TTreeNode;   
04.begin  
05.  Accept := False;   
06.  TargetNode := TTreeView(Sender).GetNodeAt(X, Y);   
07.  if (Source = Sender) and (TargetNode <> nil) then  
08.  begin  
09.    Accept := True;   
10.    SourceNode := TTreeView(Sender).Selected;   
11.    if TargetNode = SourceNode.Parent then  
12.      Accept := False;   
13.    if Accept then  
14.    begin  
15.      while (TargetNode.Parent <> nil) and (TargetNode <> SourceNode) do  
16.        TargetNode := TargetNode.Parent;   
17.      if TargetNode = SourceNode then  
18.        Accept := False;   
19.    end;   
20.  end;   
21.end; 


 

OnDragDrop是放下后节点的处理方法:

01.procedure TMainForm.TreeViewDragDrop(Sender, Source: TObject; X, Y: Integer);   
02.var  
03.  TargetNode, SourceNode: TTreeNode;   
04.begin  
05.  TargetNode := TTreeView(Sender).GetNodeAt(X, Y);   
06.  if TargetNode <> nil then  
07.  begin  
08.    SourceNode := TTreeView(Sender).Selected;   
09.    TTreeView(Sender).Items.BeginUpdate;   
10.    SourceNode.MoveTo(TargetNode, naAddChildFirst);   
11.    TTreeView(Sender).Selected := SourceNode;   
12.    TTreeView(Sender).Items.EndUpdate;   
13.  end;   
14.end; 


 

另外TreeView本身还需要设定支持拖放,俩个方法:

1: 静态设定TreeView可以拖放

procedure TMainForm.FormCreate(Sender: TObject);   
begin  
  TreeView.DragMode := dmAutomatic;   
end;  

2: 通过事件动态设定

01.procedure TMainForm.TreeViewMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);   
02.begin  
03.  if (Button = mbLeft) and (htOnItem in TTreeView(Sender).GetHitTestInfoAt(X, Y)) then  //判断是左键并且点击在Item上   
04.  begin  
05.    if (ssCtrl in Shift) then  //如果按下了Ctrl键   
06.      TTreeView(Sender).BeginDrag(False);  //允许拖放   
07.  end;   
08.end; 


////////////////////////////////////////////////////////////////////

procedure TfrmMain.TreeView1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); 
var 
      node: TTreeNode; 
begin 
      node := TreeView1.GetNodeAt(X, Y);  // 获取鼠标按下位置的节点 
   if (node <> nil) and (node.Level > 0) and (Button = mbLeft) then 
         TreeView1.BeginDrag(True);  // 启动拖动 
end;

 

  需要注意的是,TreeView 控件的 DragMode 要设置为 dmManual,才会需要执行 BeginDrag 手工启动拖动。DragMode 的缺省值就是 dmManual。

  接下来就是 OnDargOver 事件。

procedure TfrmMain.TreeView1DragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); 
var 
      node: TTreeNode; 
begin 
      node := TreeView1.GetNodeAt(X, Y); 
   // node.Level 是节点的层级,等于0时,表示是根节点(没有上级节点了) 
   // 本语句控制只能将节点拖动到与父节点平级的其他节点上,Accept表示,是否可释放 
   if (node <> nil) and (node.Level = 0) and (TreeView1.Selected.Parent <> node) then 
         Accept := True 
   else 
         Accept := False; 
end;

 

  最后是实现 OnDragDrop 事件,此事件里就要写上与业务相关的代码了。

procedure TfrmMain.TreeView1DragDrop(Sender, Source: TObject; X, Y: Integer); 
var 
      node: TTreeNode; 
begin 
      node := TreeView1.GetNodeAt(X, Y); 
   if (node <> nil) and (node.Level = 0) then 
      begin 
      // 此处用到了StateIndex,只是在生成TreeView的时候,将每条记录的主键值储存到了这里,并不代表StateIndex的实际意义 
         Query1.SQL.Text := 'update sys_config set class_id=' + IntToStr(node.StateIndex) + ' where cid=' + IntToStr(TreeView1.Selected.StateIndex); 
      if Query1.ExecSQL() > 0 then 
            TreeView1.Selected.MoveTo(node, naAddChild);  // 将节点移动到目标节点的下一级,也就是使目标节点成为被拖动节点的父节点 
      end; 
end;


















本文转自鹅倌51CTO博客,原文链接: http://blog.51cto.com/kaixinbuliao/1429684,如需转载请自行联系原作者
相关文章
Qml实用技巧:在可视元素之前半透明覆盖一个可视元素,阻止鼠标透(界面)传(防止点击到被遮挡的按钮)
Qml实用技巧:在可视元素之前半透明覆盖一个可视元素,阻止鼠标透(界面)传(防止点击到被遮挡的按钮)
Qml实用技巧:在可视元素之前半透明覆盖一个可视元素,阻止鼠标透(界面)传(防止点击到被遮挡的按钮)
|
6月前
【sgDragMove】自定义组件:自定义拖拽组件,仅支持拖拽、设置吸附屏幕边界距离。
【sgDragMove】自定义组件:自定义拖拽组件,仅支持拖拽、设置吸附屏幕边界距离。
|
6月前
|
索引
[Qt5&控件] 下拉框ComBoBox和层叠窗口StackedWidget控件组合使用
[Qt5&控件] 下拉框ComBoBox和层叠窗口StackedWidget控件组合使用
157 0
|
C#
C#之四十一 在Winform中从外部拖动节点到树形结构
C#之四十一 在Winform中从外部拖动节点到树形结构
74 0
|
Android开发
浮窗开发之窗口层级
最近在项目中遇到了这样的需求:需要在特定的其他应用之上悬浮自己的UI交互(拖动、输入等复杂的UI交互),和九游的浮窗类似,不过我们的比九游的体验更好,我们越过了很多授权的限制。 很多人都知道如何去实现一个简单的浮窗,但是却很少有人去深入的研究背后的流程机制,由于项目中浮窗交互比较复杂,遇到了些
4295 0