关于 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(类型) 第二步:前台代码 <% ...
随机推荐
- 基于Redis的爬虫平台的实现
一.需求: 1.数据抓取:目标数据的下载.解析.入库功能. 2.数据服务:黑名单.灰名单等查询服务. 3.平台监控:平台各个模块的数据实时监控. 二.WEB端效果展示: 三.架构设计 下载器.解析器. ...
- Linux最常用命令的小总结
目录及文件的基本操作: cd .. 切换到当前目录的上一级目录 cd 切换工作目录至当前用户的家目录 cd - 返回到上一个打开的目录(像遥控器上的切换键,切换到上一个播放的电视频道) ll -h ...
- PHP发送和接收POST数据
1. 发送post数据 $data = '{ "id": "17999030", "method": "sayHello" ...
- (copy) Top Ten Reasons not to use the C shell
http://www.grymoire.com/Unix/CshTop10.txt ========================================================== ...
- c++的构造函数
我刚学的知识:c++的构造函数.在在此之前一直都处于迷惑之中,现在怕忘.所以赶紧把他写下来,用来以后复习,可能有错误的地方,请大牛们指出来.c++知识相对与c来说更加抽象,但真明白了,也就那一回事.这 ...
- AppCan JSSDK模块扩展
1. 从源码开始: 我们先看源码的8188行到9525行: window.appcan && appcan.define('window',function($,export ...
- 分布式入门之2:Quorum机制
1. 全写读1(write all, read one) 全写读1是最直观的副本控制规则.写时,只有全部副本写成功,才算是写成功.这样,读取时只需要从其中一个副本上读数据,就能保证正确性. 这种规则 ...
- 【转】PowerShell入门(十):使用配置文件
转至:http://www.cnblogs.com/ceachy/archive/2013/03/01/PowerShell_Profile.html 在命令行中定义别名.变量和函数,只是将它们添加在 ...
- String空值判定
不能用 str.equalsIgnoreCase(null). 写了个判定的方法,供以后直接调用: public static boolean isEmpty(String str) { if (st ...
- Hdu 5489 合肥网络赛 1009 Removed Interval
跳跃式LIS(nlogn),在普通的转移基础上增加一种可以跨越一段距离的转移,用一颗新的树状数组维护,同时,我们还要维护跨越完一次后面的转移,所以我用了3颗树状数组.. 比赛的时候一句话位置写错了,然 ...