翼度科技»论坛 编程开发 .net 查看内容

DXP TreeList 目录树

5

主题

5

帖子

15

积分

新手上路

Rank: 1

积分
15
DXP TreeList 目录树

1.需求背景

需要一个支持勾选,拖动节点,保存各节点顺序的目录树。

2.创建目录树

在treeList控件中添加两个colunm 用来显示绑定数据和显示值。

接下来对treeList的属性进行设置
  1.             // 设置列不显示
  2.             treeList.OptionsView.ShowColumns = false;
  3.             // 设置序号列不显示
  4.             treeList.OptionsView.ShowIndicator = false;
  5.             // 设置垂直线不显示
  6.             treeList.OptionsView.ShowVertLines = false;
  7.             // 设置水平线不显示
  8.             treeList.OptionsView.ShowHorzLines = false;
  9.             // 设置焦点框为行焦点
  10.             treeList.OptionsView.FocusRectStyle = DevExpress.XtraTreeList.DrawFocusRectStyle.RowFocus;
  11.             // 隐藏第一列(数据列)
  12.             treeListColumn1.Visible = false;
  13.             // 设置不可编辑
  14.             treeList.OptionsBehavior.Editable = false;
  15.             // 设置显示复选框
  16.             treeList.OptionsView.ShowCheckBoxes = true;
  17.             // 设置勾选父节点,子节点自动全选
  18.             treeList.OptionsBehavior.AllowRecursiveNodeChecking = true;
复制代码
添加节点
  1.         private TreeListNode AppendNode(PrjTableNode node, int pid)
  2.         {
  3.             TreeListNode treeListNode = null;
  4.             Action<PrjTableNode, int> ac = (arg1, arg2) =>
  5.              {
  6.                  treeListNode = treeList.AppendNode(new object[] { node, node.Alias }, pid, 0, 0, 0);
  7.              };
  8.             var tt = treeList.Invoke(ac, new object[] { node, pid });
  9.             SetNodeCheckState(treeListNode);
  10.             return treeListNode;
  11.         }
复制代码
主要用到treeList.AppendNode()方法,方法定义如下
  1. AppendNode(object nodeData, int parentNodeId, int imageIndex, int selectImageIndex, int stateImageIndex)
复制代码

  • nodeData : object 类型的参数,这里传入object[]数组对象,数组对应treeList的列,这里第一列是数据,第二列用来显示,因此需要将第一列隐藏。
  • parentNodeId :父节点ID
  • imageIndex : 节点图标索引,这里没有图标就给任意一个数字
  • selectImageIndex : 节点被选择后显示的图标索引
  • stateImageIndex : 状态图标索引
此时目录树就创建好了。
2.1 设置目录树选中节点的背景色

添加CustomDrawNodeCell事件
  1.             // 设置行背景色
  2.             treeList.CustomDrawNodeCell -= TreeList_CustomDrawNodeCell;
  3.             treeList.CustomDrawNodeCell += TreeList_CustomDrawNodeCell;
复制代码
设置颜色
  1.         private void TreeList_CustomDrawNodeCell(object sender, DevExpress.XtraTreeList.CustomDrawNodeCellEventArgs e)
  2.         {
  3.             if (e.Node.Selected)
  4.             {
  5.                 e.Appearance.BackColor = Color.FromArgb(192, 192, 255);
  6.             }
  7.         }
复制代码
2.2 控制目录树节点的勾选框是否显示

添加CustomDrawNodeCheckBox事件
  1.             // 控制复选框显隐
  2.             treeList.CustomDrawNodeCheckBox -= TreeList_CustomDrawNodeCheckBox;
  3.             treeList.CustomDrawNodeCheckBox += TreeList_CustomDrawNodeCheckBox;
复制代码
  1.         private void TreeList_CustomDrawNodeCheckBox(object sender, DevExpress.XtraTreeList.CustomDrawNodeCheckBoxEventArgs e)
  2.         {
  3.             // 满足逻辑条件的 ,将 e.Handled = true 即可
  4.             if ((e.Node.GetValue(treeListColumn1) as PrjTableNode)?.Type == ConstClass1.PRJ_TYPE_ID)
  5.             {
  6.                 //e.Handled = true;
  7.             }
  8.         }
复制代码
2.3 节点拖拽

这里的需求是只允许同级节点内部拖动,也不允许拖动到节点子集。
设置属性OptionsDragAndDrop.DragNodesMode = DragNodesMode.Single
添加DragOver,DragDrop,AfterDragNode事件
  1.             // 设置节点拖拽
  2.             treeList.OptionsDragAndDrop.DragNodesMode = DragNodesMode.Single;
  3.                    // 处理拖动时的逻辑
  4.             treeList.DragOver -= TreeList_DragOver;
  5.             treeList.DragOver += TreeList_DragOver;
  6.                    // 处理拖动结束时的逻辑
  7.             treeList.DragDrop -= TreeList_DragDrop;
  8.             treeList.DragDrop += TreeList_DragDrop;
  9.                    // 处理拖动后的逻辑
  10.             treeList.AfterDragNode -= TreeList_AfterDragNode;
  11.             treeList.AfterDragNode += TreeList_AfterDragNode;
复制代码
DragOver 用来处理拖动时的逻辑
当有节点需要禁止拖动时,满足逻辑时,设置 e.Effect = DragDropEffects.None;即可
  1.        private void TreeList_DragOver(object sender, DragEventArgs e)
  2.         {
  3.             var currNode = treeList.FocusedNode;
  4.             var curNodeData = currNode.GetValue(treeListColumn1) as PrjTableNode;
  5.             if (curNodeData == null)
  6.             {
  7.                 return;
  8.             }
  9.             if (!curNodeData.CanDrag)
  10.             {
  11.                 e.Effect = DragDropEffects.None;
  12.             }
  13.         }
复制代码
DragDrop 用来处理拖动结束时的逻辑
  1.         private void TreeList_DragDrop(object sender, DragEventArgs e)
  2.         {
  3.             // 当前节点的父节点变化,则不允许拖动
  4.             var dragNode = e.Data.GetData(typeof(TreeListNode)) as TreeListNode;
  5.             var sourceParent = dragNode.ParentNode.GetValue(treeListColumn1) as PrjTableNode;
  6.             var targetNode = treeList.CalcHitInfo(treeList.PointToClient(MousePosition)).Node;
  7.             if (targetNode == null)
  8.             {
  9.                 return;
  10.             }
  11.             PrjTableNode targetNodeParent = null;
  12.             if (targetNode.ParentNode != null)
  13.             {
  14.                 targetNodeParent = targetNode.ParentNode.GetValue(treeListColumn1) as PrjTableNode;
  15.             }
  16.             // 发生跨级移动
  17.             if (sourceParent.Id != targetNodeParent.Id)
  18.             {
  19.                 e.Effect = DragDropEffects.None;
  20.                 return;
  21.             }
  22.             // 移到子集
  23.             if (AjustDirection(sender, e) == DragInsertPosition.AsChild)
  24.             {
  25.                 e.Effect = DragDropEffects.None;
  26.                 return;
  27.             }
  28.         }
复制代码
  1.         /// <summary>
  2.         /// 移动过程中的方向
  3.         /// </summary>
  4.         /// <param name="sender"></param>
  5.         /// <param name="e"></param>
  6.         /// <returns></returns>
  7.         private DragInsertPosition AjustDirection(object sender, DragEventArgs e)
  8.         {
  9.             var tl = sender as TreeList;
  10.             //var dragNode = e.Data.GetData(typeof(TreeListNode)) as TreeListNode;
  11.             //var hit = tl.CalcHitInfo(tl.PointToClient(new Point(e.X, e.Y)));
  12.             var pi = typeof(TreeList).GetProperty("Handler", BindingFlags.Instance | BindingFlags.NonPublic);
  13.             var handler = (TreeListHandler)pi.GetValue(tl, null);
  14.             return handler.StateData.DragInfo.DragInsertPosition;
  15.         }
复制代码
AfterDragNode 用来处理拖动结束后的逻辑
  1.         private void TreeList_AfterDragNode(object sender, AfterDragNodeEventArgs e)
  2.         {
  3.             // TODO:...
  4.         }
复制代码
3.总结

treeList是一个很强大的控件,用来处理树状结构。本次需求中,处理节点拖拽话费了较长时间,也网上找了很多博文,但是都没有直接解决我的问题,因此在这里做个笔记。
后记:纸上得来终觉浅,绝知此事要躬行

来源:https://www.cnblogs.com/ycit/archive/2023/08/04/17604994.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具