DXP TreeList 目录树

  • DXP TreeList 目录树已关闭评论
  • 81 次浏览
  • A+
所属分类:.NET技术
摘要

需要一个支持勾选,拖动节点,保存各节点顺序的目录树。在treeList控件中添加两个colunm 用来显示绑定数据和显示值。


DXP TreeList 目录树

1.需求背景

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

DXP TreeList 目录树

2.创建目录树

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

DXP TreeList 目录树

接下来对treeList的属性进行设置

            // 设置列不显示             treeList.OptionsView.ShowColumns = false;             // 设置序号列不显示             treeList.OptionsView.ShowIndicator = false;             // 设置垂直线不显示             treeList.OptionsView.ShowVertLines = false;             // 设置水平线不显示             treeList.OptionsView.ShowHorzLines = false;             // 设置焦点框为行焦点             treeList.OptionsView.FocusRectStyle = DevExpress.XtraTreeList.DrawFocusRectStyle.RowFocus;             // 隐藏第一列(数据列)             treeListColumn1.Visible = false;             // 设置不可编辑             treeList.OptionsBehavior.Editable = false;             // 设置显示复选框             treeList.OptionsView.ShowCheckBoxes = true;             // 设置勾选父节点,子节点自动全选             treeList.OptionsBehavior.AllowRecursiveNodeChecking = true;   

添加节点

        private TreeListNode AppendNode(PrjTableNode node, int pid)         {             TreeListNode treeListNode = null;             Action<PrjTableNode, int> ac = (arg1, arg2) =>              {                  treeListNode = treeList.AppendNode(new object[] { node, node.Alias }, pid, 0, 0, 0);              };             var tt = treeList.Invoke(ac, new object[] { node, pid });             SetNodeCheckState(treeListNode);             return treeListNode;         } 

主要用到treeList.AppendNode()方法,方法定义如下

 AppendNode(object nodeData, int parentNodeId, int imageIndex, int selectImageIndex, int stateImageIndex) 
  • nodeData : object 类型的参数,这里传入object[]数组对象,数组对应treeList的列,这里第一列是数据,第二列用来显示,因此需要将第一列隐藏。
  • parentNodeId :父节点ID
  • imageIndex : 节点图标索引,这里没有图标就给任意一个数字
  • selectImageIndex : 节点被选择后显示的图标索引
  • stateImageIndex : 状态图标索引

此时目录树就创建好了。

2.1 设置目录树选中节点的背景色

添加CustomDrawNodeCell事件

            // 设置行背景色             treeList.CustomDrawNodeCell -= TreeList_CustomDrawNodeCell;             treeList.CustomDrawNodeCell += TreeList_CustomDrawNodeCell; 

设置颜色

        private void TreeList_CustomDrawNodeCell(object sender, DevExpress.XtraTreeList.CustomDrawNodeCellEventArgs e)         {             if (e.Node.Selected)             {                 e.Appearance.BackColor = Color.FromArgb(192, 192, 255);             }         } 

2.2 控制目录树节点的勾选框是否显示

添加CustomDrawNodeCheckBox事件

            // 控制复选框显隐             treeList.CustomDrawNodeCheckBox -= TreeList_CustomDrawNodeCheckBox;             treeList.CustomDrawNodeCheckBox += TreeList_CustomDrawNodeCheckBox; 
        private void TreeList_CustomDrawNodeCheckBox(object sender, DevExpress.XtraTreeList.CustomDrawNodeCheckBoxEventArgs e)         {             // 满足逻辑条件的 ,将 e.Handled = true 即可             if ((e.Node.GetValue(treeListColumn1) as PrjTableNode)?.Type == ConstClass1.PRJ_TYPE_ID)             {                 //e.Handled = true;             }         } 

2.3 节点拖拽

这里的需求是只允许同级节点内部拖动,也不允许拖动到节点子集。

设置属性OptionsDragAndDrop.DragNodesMode = DragNodesMode.Single

添加DragOver,DragDropAfterDragNode事件

            // 设置节点拖拽             treeList.OptionsDragAndDrop.DragNodesMode = DragNodesMode.Single; 		   // 处理拖动时的逻辑              treeList.DragOver -= TreeList_DragOver;             treeList.DragOver += TreeList_DragOver; 		   // 处理拖动结束时的逻辑              treeList.DragDrop -= TreeList_DragDrop;             treeList.DragDrop += TreeList_DragDrop; 		   // 处理拖动后的逻辑              treeList.AfterDragNode -= TreeList_AfterDragNode;             treeList.AfterDragNode += TreeList_AfterDragNode; 

DragOver 用来处理拖动时的逻辑

当有节点需要禁止拖动时,满足逻辑时,设置 e.Effect = DragDropEffects.None;即可

       private void TreeList_DragOver(object sender, DragEventArgs e)         {             var currNode = treeList.FocusedNode;             var curNodeData = currNode.GetValue(treeListColumn1) as PrjTableNode;             if (curNodeData == null)             {                 return;             }             if (!curNodeData.CanDrag)             {                 e.Effect = DragDropEffects.None;             }         } 

DragDrop 用来处理拖动结束时的逻辑

        private void TreeList_DragDrop(object sender, DragEventArgs e)         {             // 当前节点的父节点变化,则不允许拖动             var dragNode = e.Data.GetData(typeof(TreeListNode)) as TreeListNode;             var sourceParent = dragNode.ParentNode.GetValue(treeListColumn1) as PrjTableNode;              var targetNode = treeList.CalcHitInfo(treeList.PointToClient(MousePosition)).Node;             if (targetNode == null)             {                 return;             }             PrjTableNode targetNodeParent = null;             if (targetNode.ParentNode != null)             {                 targetNodeParent = targetNode.ParentNode.GetValue(treeListColumn1) as PrjTableNode;             }             // 发生跨级移动             if (sourceParent.Id != targetNodeParent.Id)             {                 e.Effect = DragDropEffects.None;                 return;             }             // 移到子集             if (AjustDirection(sender, e) == DragInsertPosition.AsChild)             {                 e.Effect = DragDropEffects.None;                 return;             }         } 
        /// <summary>         /// 移动过程中的方向         /// </summary>         /// <param name="sender"></param>         /// <param name="e"></param>         /// <returns></returns>         private DragInsertPosition AjustDirection(object sender, DragEventArgs e)         {             var tl = sender as TreeList;             //var dragNode = e.Data.GetData(typeof(TreeListNode)) as TreeListNode;             //var hit = tl.CalcHitInfo(tl.PointToClient(new Point(e.X, e.Y)));             var pi = typeof(TreeList).GetProperty("Handler", BindingFlags.Instance | BindingFlags.NonPublic);             var handler = (TreeListHandler)pi.GetValue(tl, null);             return handler.StateData.DragInfo.DragInsertPosition;          } 

AfterDragNode 用来处理拖动结束后的逻辑

        private void TreeList_AfterDragNode(object sender, AfterDragNodeEventArgs e)         {             // TODO:...          } 

3.总结

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

后记:纸上得来终觉浅,绝知此事要躬行