关于 DevExpress.XtraTreeList.TreeList 树形控件 的操作
作为一个C#程序员,在写程序时一直以来都使用的微软那一套控件,用起来特别爽,可是最近公司的一个项目用到了DevExpress框架,不用不知道,一用吓一跳,不得不承认这个框架确实很强大,效果也很炫,但是用这个框架也遇到了很多让我头疼的问题,由于该控件可能使用的人少,在网上能查到的解决办法实在有限,所以在解决问题时效率低得让我有些接受不了,所以再此把我遇到的一些问题和解决思路以及解决结果给大家分享一下,该篇博文只针对DevExpress.XtraTreeList.TreeList 树形控件来说以下简称(Dev树形),let's do it\(≧▽≦)/:
首先罗列出所需功能:
1、树形的绑定(给数据源对树形进行绑定)
2、树形节点的查找(根据用户输入的名字进行模糊查询节点数据:重点在于根据子节点反向递归父节点)
3、树形的右键选中节点(在节点上点击右键时就选中节点)
4、根据ID选中节点(该功能着实让我头疼了好久)
依次展示出这几个功能的效果图:
树形的绑定:
由于 Dev树形 在树形绑定时需要特定格式,那么我们先来展示出 Dev树形 所要使用到的实体类代码:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace BW.PropertyModel.Class
- {
- public class TreeListModel
- {
- #region 字段属性
- private int id;
- /// <summary>
- /// 节点编号
- /// </summary>
- public int ID
- {
- get { return id; }
- set { id = value; }
- }
- private int parentID;
- /// <summary>
- /// 父节点编号
- /// </summary>
- /// <value>The parent ID.</value>
- public int ParentID
- {
- get { return parentID; }
- set { parentID = value; }
- }
- private string menuName;
- /// <summary>
- /// 菜单名称
- /// </summary>
- public string MenuName
- {
- get { return menuName; }
- set { menuName = value; }
- }
- private object tag;
- /// <summary>
- /// 用于装节点对象
- /// </summary>
- public object Tag
- {
- get { return tag; }
- set { tag = value; }
- }
- #endregion
- }
- }
解释一下这四个字段的用途:ID 是独一无二的,在树形绑定时可以使用数据库中你要绑定的那个对象的ID;ParentID用于 Dev树形 识别节点所属关系(也就是该节点属哪个节点);MenuName 用于 Dev树形 节点的显示名; Tag用于装你所需要的任意对象
接下来再附图给大家展示给 Dev树形 绑定这几个字段,第二张图是接着第一张未展示完的地方,这8个地方我就不一一解释了,自己下来仔细看看,他们的含义一目了然的,这里需要注意的一点是:visible这个属性;接下来说一说数据源的事:数据源要根据数据库中的数据进行递归处理,附上递归处理和初始化树形的代码:
- /// <summary>
- /// 加载设备树形
- /// </summary>
- public void InitFacilityTree()
- {
- List<TreeListModel> list = new List<TreeListModel>();
- int systemId = 0;
- if (this.cmbSystemClassify.EditValue != null)
- {
- int.TryParse(this.cmbSystemClassify.EditValue.ToString(), out systemId);
- }
- List<BW.DMSystem.Core.Entity.ModelManageInfo> temp = BLLFactory<BW.DMSystem.Core.BLL.ModelManage>.Instance.GetAll(string.Format("where IsGallery = 0 and SystemID = {0} order by ID asc", systemId)); //查询数据库中某个系统的数据
- TreeList(0, ref list, temp); //这里传的0表示 根节点
- this.tvFacilityModel.KeyFieldName = "ID"; //这里绑定的ID的值必须是独一无二的
- this.tvFacilityModel.ParentFieldName = "ParentID"; //表示使用parentID进行树形绑定
- this.tvFacilityModel.DataSource = list; //绑定数据源
- this.tvFacilityModel.ExpandAll(); //默认展开所有节点
- }
- /// <summary>
- /// 递归调用——正向生成树形所需结构
- /// </summary>
- /// <param name="parentId">根节点的父编码默认为0</param>
- /// <param name="listData">树形绑定的数据集合</param>
- /// <param name="modelList">某系统的结构数据</param>
- private void TreeList(int parentId, ref List<TreeListModel> listData, List<BW.DMSystem.Core.Entity.ModelManageInfo> modelList)
- {
- List<BW.DMSystem.Core.Entity.ModelManageInfo> tmp = modelList.Where(model => model.ParentCode == parentId).ToList(); //这句话很重要,对数据进行筛选全靠它
- foreach (var item in tmp)
- {
- TreeListModel temp = new TreeListModel();
- temp.ID = item.ID;
- temp.MenuName = item.Name;
- temp.ParentID = parentId;
- temp.Tag = item;
- listData.Add(temp);
- TreeList(item.ID, ref listData, modelList);
- }
- }
我这里使用的树形是根据系统分了类的,你如果不需要可以不管 根据注释应该能猜出个大概 树形的绑定就算告一段落了
树形节点的查找:
效果图是最开始的第二张图
代码:
- /// <summary>
- /// 搜索事件
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void btnSearch_Click(object sender, EventArgs e)
- {
- List<TreeListModel> list = new List<TreeListModel>();
- List<int> listId = new List<int>(); //这个集合用于存储已经加入了的父节点ID,因为有些子节点可能同在一个父节点下若重复插入同ID的数据会报错
- string inputStr = this.txtModelName.Text.Trim();
- string systemId = string.Empty;
- if (this.cmbSystemClassify.EditValue != null)
- {
- systemId = this.cmbSystemClassify.EditValue.ToString();
- }
- else
- {
- systemId = "0";
- }
- if (string.IsNullOrEmpty(inputStr))
- {
- //如果为空则查询所有
- List<BW.DMSystem.Core.Entity.ModelManageInfo> temp = BLLFactory<BW.DMSystem.Core.BLL.ModelManage>.Instance.GetAll(string.Format("where IsGallery = 0 and SystemID = '{0}' order by ID asc", systemId));
- TreeList(0, ref list, temp);
- }
- else
- {
- //查询出所有数据
- List<BW.DMSystem.Core.Entity.ModelManageInfo> allData = BLLFactory<BW.DMSystem.Core.BLL.ModelManage>.Instance.GetAll(string.Format("where IsGallery = 0 and SystemID = '{0}' order by ID asc", systemId));
- //查询出满足条件的
- List<BW.DMSystem.Core.Entity.ModelManageInfo> temp = BLLFactory<BW.DMSystem.Core.BLL.ModelManage>.Instance.GetAll(string.Format("where IsGallery = 0 and IsModel = 1 and SystemID = '{0}' and Name like '%{1}%' order by ID asc", systemId, inputStr));
- for (int i = 0; i < temp.Count; i++)
- {
- TreeListModel currNode = new TreeListModel();
- currNode.ID = temp[i].ID;
- currNode.MenuName = temp[i].Name;
- currNode.ParentID = temp[i].ParentCode;
- currNode.Tag = temp[i];
- list.Add(currNode);
- listId.Add(temp[i].ID);
- TreeList_fanxiang(temp[i].ParentCode, ref list, ref listId, allData);
- }
- }
- this.tvFacilityModel.KeyFieldName = "ID";
- this.tvFacilityModel.ParentFieldName = "ParentID";
- this.tvFacilityModel.DataSource = list;
- this.tvFacilityModel.ExpandAll();
- }
- }
- /// <summary>
- /// 递归调用——反向查找节点的根节点
- /// </summary>
- /// <param name="currId">根节点的父编码默认为0</param>
- /// <param name="listData">树形绑定的数据集合</param>
- /// <param name="modelList">某系统的结构数据</param>
- private void TreeList_fanxiang(int parentId, ref List<TreeListModel> listData, ref List<int> listId, List<BW.DMSystem.Core.Entity.ModelManageInfo> modelList)
- {
- List<BW.DMSystem.Core.Entity.ModelManageInfo> tmp = modelList.Where(model => model.ID == parentId).ToList(); //正向和反向的最终区别就在于这句话
- foreach (var item in tmp)
- {
- TreeListModel temp = new TreeListModel();
- temp.ID = item.ID;
- temp.MenuName = item.Name;
- temp.ParentID = item.ParentCode;
- temp.Tag = item;
- if (!listId.Contains(item.ID))
- {
- listData.Add(temp);
- listId.Add(item.ID);
- }
- TreeList_fanxiang(item.ParentCode, ref listData, ref listId, modelList);
- }
- }
根据注释理解代码的含义,节点查找也告一段落了。
树形节点的右键选中:
在节点上鼠标右键点击时默认是不会选中该节点的,这个功能说简单不简单说复杂也不复杂,我就直接附上代码来
- /// <summary>
- /// 鼠标右键事件
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void tvFacilityModel_MouseUp(object sender, MouseEventArgs e) 需要注意的是 这个事件不要搞错了
- {
- DevExpress.XtraTreeList.TreeList tree = sender as DevExpress.XtraTreeList.TreeList;
- if ((e.Button == MouseButtons.Right) && (ModifierKeys == Keys.None) && (tvFacilityModel.State == TreeListState.Regular)) //这里的几个条件只有第一个条件有点用,其他的可有可无
- {
- Point p = new Point(Cursor.Position.X, Cursor.Position.Y); //获取到鼠标点击的坐标位置
- TreeListHitInfo hitInfo = tree.CalcHitInfo(e.Location);
- if (hitInfo.HitInfoType == HitInfoType.Cell)
- {
- tree.SetFocusedNode(hitInfo.Node); //这句话就是关键,用于选中节点
- TreeListNode selectNode = this.tvFacilityModel.FocusedNode;
- BW.DMSystem.Core.Entity.ModelManageInfo modelObj = selectNode.GetValue(3) as BW.DMSystem.Core.Entity.ModelManageInfo;
- if (modelObj == null)
- {
- return;
- }
- if (modelObj.IsModel)
- {
- this.ModelID = modelObj.ID.ToString();
- this.ModelName = modelObj.Name;
- popupMenu1.ShowPopup(p);
- }
- }
- }
- }
再来看看微软的右键选中节点的代码:
- private void treeView1_MouseDown(object sender, MouseEventArgs e)
- {
- if (e.Button == MouseButtons.Right)
- {
- treeView1.SelectedNode = treeView1.GetNodeAt(e.X, e.Y);
}- }
诶,有种说不出的悲伤。。。OK该功能已Over
根据ID选中节点:
这里的思路起始很简单,只要找出树形中已经绑定的数据源中某个节点的ID的值和传递过来的值一样就选中就行了,但是就是这样一个简单的思路 Dev树形 却搞了很多花样着实让我蛋疼不已啊,原本想直接遍历树形的节点的,但是调试中发现 this.tvFacilityModel.Nodes.Count 这句话居然返回的只有第一级的节点,那怎么办呢?——又只有用递归查找了涩 诶,附上递归查找代码:
- /// <summary>
- /// 递归查找子节点
- /// </summary>
- /// <param name="node"></param>
- /// <param name="ID"></param>
- /// <returns></returns>
- private TreeListNode nodes(TreeListNode node, string ID)
- {
- TreeListNode returnNodex = null;
- if (node.HasChildren)
- {
- for (int i = 0; i < node.Nodes.Count; i++)
- {
- if (node.Nodes[i].GetValue("ID").ToString() == ID)
- {
- returnNodex = node.Nodes[i];
- break;
- }
- else
- {
- returnNodex = nodes(node.Nodes[i], ID);
- }
- }
- }
- return returnNodex;
- }
最后再使用 this.tvFacilityModel.FocusedNode = selectNode; 将返回来的节点设置给 Dev树形 就OK了。
经过这次对树形控件的使用,没有多大的收获,收获最大的就是对递归这种方式有了更深的认识,也熟练了不少,Dev树形控件我的痛啊!~~~~(>_<)~~~~
好了,也许我的代码不够精简,目前的技术也就写的出这样的代码,希望广大朋友不要介意,有什么意见和需要帮助请进行评论或留言,多多沟通有助于发展。
关于 DevExpress.XtraTreeList.TreeList 树形控件 的操作的更多相关文章
- Devexpress treelist 树形控件 实现带三种状态的CheckBox
树形控件是使用频率很高的一种控件.对于属性控件往往需要下面两个功能 1.TreeList带有CheckBox,并且节点要有三种状态(所有的子节点都选中,所有的子节点都没选择,一部分子节点选中).使用 ...
- Visual studio C++ MFC之树形控件Tree Control
背景 本篇旨在MSDN帮助文档下总结树形控件Tree Control的使用,并列出碰到的具体问题. 正文 树形控件Tree Control的类则是CTreeCtrl,具体成员对象详见链接,以下则描述一 ...
- 在DevExpress中使用CameraControl控件进行摄像头图像采集
在我们以前的项目了,做摄像头的图片采集,我们一般还是需要做一个封装处理的,在较新版本的DevExpress控件里面,增加了一个CameraControl控件,可以直接调用摄像头显示的,因此也可以做头像 ...
- js树形控件—zTree使用总结
0 zTree简介 树形控件的使用是应用开发过程中必不可少的.zTree 是一个依靠 jQuery 实现的多功能 “树插件”.优异的性能.灵活的配置.多种功能的组合是 zTree 最大优点. 0.0 ...
- 基于Bootstrap的JQuery TreeView树形控件,数据支持json字符串、list集合(MVC5)<二>
上篇博客给大家介绍了基于Bootstrap的JQuery TreeView树形控件,数据支持json字符串.list集合(MVC5)<一>, 其中的两种方式都显得有些冗余.接着上篇博客继续 ...
- 在DevExpress中使用WizardControl控件构建多步向导界面
利用好的界面控件,往往能做成比较界面体验效果.在一些界面操作里面,我们可能把它拆分为几部进行处理,这个时候引入WizardControl向导控件应该是比较不错的选择了.多步的处理方式,可以让用户避免一 ...
- DevExpress winform XtraEditor常用控件
最近在公司里面开始使用DevExpress winform的第三方控件进行开发和维护,这里整理一些常用控件的资料以便于后续查看 ComboBoxEdit 这个控件和winform自带的控件差不多,使用 ...
- js树形控件
js树形控件 ztree http://www.treejs.cn/
- TreeView树形控件递归绑定数据库里的数据
TreeView树形控件递归绑定数据库里的数据. 第一种:性能不好 第一步:数据库中查出来的表,字段名分别为UNAME(显示名称),DID(关联数据),UTYPE(类型) 第二步:前台代码 <% ...
随机推荐
- vim - buffer
1. buffer switching http://vim.wikia.com/wiki/Easier_buffer_switching :buffer:ls:files 2. vim defaul ...
- c语言1
1.c语言的执行过程: 源代码:source code,使用某种计算机语言书写的代码. 编译:compile 对源代码进行翻译的过程. 编译器:compiler 负责编译工具. gcc:一款通用的编译 ...
- IOS开发UISearchBar失去第一响应者身份后,取消按钮不执行点击事件的问题
在iOS开发中,使用UISearchBar的时候,当搜索框失去焦点的时候,取消按钮是默认不能点击的,如图按钮的颜色是灰色的: 这是因为此时取消按钮的enabled属性被设置为NO了,那么当我们需要让 ...
- C语言pow函数编写
C语言pow函数编写 #include<stdio.h> double chaoba(double f,double q); //声明自定义函数 void main(void) { dou ...
- C# 创建Windows服务
创建windows服务项目 2 右键点击Service1.cs,查看代码, 用于编写操作逻辑代码 3 代码中OnStart用于执行服务事件,一般采用线程方式执行方法,便于隔一段事件执行一回 END ...
- Javascript模块化编程(二):AMD规范(转)
这个系列的第一部分介绍了Javascript模块的基本写法,今天介绍如何规范地使用模块. (接上文) 七.模块的规范 先想一想,为什么模块很重要? 因为有了模块,我们就可以更方便地使用别人的代码,想要 ...
- eclipse安装zylin embedded cdt失败解决办法
最近再搞嵌入式开发,之前用惯了IDE调试单片机的那种方式,开发2440和am3358驱动时候无法方便的查看寄存器和变量,憋的抓耳挠腮,不爽得很,没有可视化环境进行实时调试观察,太特么蛋疼了.感觉这种情 ...
- .net之工作流工程展示及代码分享(预告)
最近在帮公司做一个工作流程序模块,要求是可以嵌入到各种现有的程序中去.我想把自己制作的思路和过程同大家分享. 先上一张结构图: 由于该项目我一个人做,所以系统结构不能太复杂. 用到的技术主要有:DDD ...
- C语言函数的声明以及函数原型
C语言代码由上到下依次执行,原则上函数定义要出现在函数调用之前,否则就会报错.但在实际开发中,经常会在函数定义之前使用它们,这个时候就需要提前声明.所谓声明(Declaration),就是告诉编译器我 ...
- 详解:数据库名、实例名、ORACLE_SID、数据库域名、全局数据库名、服务名及手工脚本创建oracle数据库
数据库名.实例名.数据库域名.全局数据库名.服务名 , 这是几个令很多初学者容易混淆的概念.相信很多初学者都与我一样被标题上这些个概念搞得一头雾水.我们现在就来把它们弄个明白. 一.数据库名 什么是数 ...