DXP TreeList 目录树
DXP TreeList 目录树
1.需求背景
需要一个支持勾选,拖动节点,保存各节点顺序的目录树。

2.创建目录树
在treeList控件中添加两个colunm 用来显示绑定数据和显示值。

接下来对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,DragDrop,AfterDragNode事件
// 设置节点拖拽
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是一个很强大的控件,用来处理树状结构。本次需求中,处理节点拖拽话费了较长时间,也网上找了很多博文,但是都没有直接解决我的问题,因此在这里做个笔记。
后记:纸上得来终觉浅,绝知此事要躬行
DXP TreeList 目录树的更多相关文章
- Java生成菜单树(目录树)的几种方式
本文介绍两种不同生成多级目录树的方式:1. 递归生成,2. map+list 集合生成.最下方会附上完整代码. 生成树的基本规则:子节点的par_id等于父节点的id. 1. 实体类 import ...
- 【.net 深呼吸】将目录树转化为文本
大伙都知道,文件系统是树形结构的,有时候我们会想到把目录的层次结构变为纯文本形式,就像这样: ├─Windows-universal-samples-master │ ├─Samples │ │ ├─ ...
- python 小程序 复制目录树
1. 将一个目录树完全复制到另外一个目录下面 import os, sys """ 复制目录树 """ maxloadsize = 1024 ...
- vs切换当前编辑文件时自动定位目录树
在编辑区,切换当前编辑文件时(单击.cpp或.h文件选项卡),"解决方案资源管理器"目录树会自动定位当前编辑的文件,并以灰色标识,当一个解决方案中的工程数目数目很多,每个工程下面又 ...
- 14.KVM安装之脚本和镜像目录树准备
1.php脚本需要先安装PHP环境,Apache服务器必须支持PHP $ yum install -y php #安装PHP $ php -v #查看是 ...
- HBase 在HDFS 上的目录树
总所周知,HBase 是天生就是架设在 HDFS 上,在这个分布式文件系统中,HBase 是怎么去构建自己的目录树的呢? 这里只介绍系统级别的目录树. 一.0.94-cdh4.2.1版本 系 ...
- 完整学习git三 查看暂存区目录树 git diff
1显示暂存区中的目录树 git ls-files git ls-tree git diff 魔法 1工作区与暂存区比较 git diff 2工作区与HEAD比较 git diff HEAD 3暂存区与 ...
- 页面设计--Tree目录树
Tree目录树控件属性: 根据数据集合来配置相应的信息 加载模式有自动加载.自定加载 web中显示效果图:
- 原创的基于HTML/CSS/JavaScript的层级目录树
之前参加过一些基于HTML/CSS/JavaScript的项目,当在页面中需要生成一颗目录树时,总是首先想着网上有没有现成的生成树的源代码,比如dtree.zthee,或者使用一些javascript ...
- Linux目录树
Linux目录树(directory tree) 分层结构(不同于数据库文件系统),单个文件/目录的最大长度为255个字符,完整路径为4096个字符 特殊的文件系统 文件系统 挂载点 说明 Root ...
随机推荐
- 深入理解 python 虚拟机:描述器的王炸应用-property、staticmethod 和 classmehtod
深入理解 python 虚拟机:描述器的王炸应用-property.staticmethod 和 classmehtod 在本篇文章当中主要给大家介绍描述器在 python 语言当中有哪些应用,主要介 ...
- 文心一言 VS chatgpt (6)-- 算法导论2.3 1~2题
一.使用图 2-4作为模型,说明归并排序在数组 A=(3,41,52,26,38,57,9,49)上的操作. 文心一言: 使用图 2-4作为模型,说明归并排序在数组 A=(3,41,52,26,38, ...
- 2020-10-11:一条sql语句执行时间过长,应该如何优化?从哪些方面进行优化?
福哥答案2020-10-11:#福大大架构师每日一题# 简单回答:执行计划调优.语句调优.索引调优.设计调优.业务调优. 中级回答:时间有限,回答得不全面.1.执行计划调优熟读执行计划,十大参数. 2 ...
- defer有什么用呢
1. 简介 本文将从一个资源回收问题引入,引出defer关键字,并对其进行基本介绍.接着,将详细介绍在资源回收.拦截和处理panic等相关场景下defer的使用. 进一步,介绍defer的执行顺序,以 ...
- Module not found: Error: Can't resolve 'axios' in 'D:\BaiduSyncdisk\vue-cli-project\dc_vue3\src\utils'
Module not found: Error: Can't resolve 'axios' in 'D:\BaiduSyncdisk\vue-cli-project\dc_vue3\src\util ...
- GPT大语言模型Alpaca-lora本地化部署实践【大语言模型实践一】
模型介绍 Alpaca模型是斯坦福大学研发的LLM(Large Language Model,大语言)开源模型,是一个在52K指令上从LLaMA 7B(Meta公司开源的7B)模型微调而来,具有70亿 ...
- es笔记一之es安装与介绍
本文首发于公众号:Hunter后端 原文链接:es笔记一之es安装与介绍 首先介绍一下 es,全名为 Elasticsearch,它定义上不是一种数据库,是一种搜索引擎. 我们可以把海量数据都放到 e ...
- 在DevExpress中使用BandedGridView表格实现多行表头的处理
在之前较早随笔中介绍过实现多行表头的处理,通过手工创建字段以及映射数据源字段属性的方式实现,有些客户反映是否可以通过代码方式更方便的创建对应的处理操作,因此本篇随笔继续探讨这个多行表头的处理的操作,使 ...
- GitLib详细使用手册(windows系统)
Git是一个开源的分布式版本控制系统,可以有效.高速地处理从很小到非常大的项目版本管理. 对gitlab的常见的使用有建立仓库.提交代码.更新代码.回滚代码.显示/修改日志.拉取分支.解决冲突.设置比 ...
- celery 组件在django环境应用
第一步安装 pip install celery==4.4 第二步 配置环境 # ############################# celery 配置连接redis ############ ...