关于 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(类型) 第二步:前台代码 <% ...
随机推荐
- 第三篇:白话tornado源码之请求来了
上一篇<白话tornado源码之待请求阶段>中介绍了tornado框架在客户端请求之前所做的准备(下图1.2部分),本质上就是创建了一个socket服务端,并进行了IP和端口的绑定,但是未 ...
- Android 基于Android的手机邮件收发(JavaMail)之四(邮件的发送)
上一个邮件的接受,因为不当操作,保存未完成,一切东西都得从头开始那就先从邮件发送来吧. 先下我们做一个较为简单的邮件发送 以下是源代码:相信看过上篇文章所给连接的人,对于javamail应该都有了一定 ...
- log4net 按时间输出日志
参考:(转)非常完善的Log4net详细说明 log4net 按天与按小时记日志的配置 Log4net 中输出日志到文件,文件名根据日期生成 log4net按日志级别(debug,info,warn, ...
- ASP.NET MVC 表单submit()
HTML代码 <form id="frmLogin"> <div class="form-group has-feedback"> &l ...
- JS新API标准 地理定位(navigator.geolocation)/////////zzzzzzzzzzz
在新的API标准中,可以通过navigator.geolocation来获取设备的当前位置,返回一个位置对象,用户可以从这个对象中得到一些经纬度的相关信息. navigator.geolocation ...
- windows批处理的介绍
扩展名是bat(在nt/2000/xp/2003下也可以是cmd)的文件就是批处理文件. 首先批处理文件是一个文本文件,这个文件的每一行都是一条DOS命令(大部分时候就好象我们在DOS提示符下执行的命 ...
- ubuntu配置tftp服务
ubuntu配置TFTP服务: TFTP是用来下载远程文件的最简单的网络协议,基于UDP协议.xinetd是新一代的网络守护进程服务程序,经常用于管理多种轻量型internet服务. sudo apt ...
- javaweb 学习资源
http://jinnianshilongnian.iteye.com/category/231099
- python实现汉诺塔
经典递归算法汉诺塔分析: 当A柱子只有1个盘子,直接A --> C 当A柱子上有3个盘子,A上第一个盘子 --> B, A上最后一个盘子 --> C, B上所有盘子(1个) --&g ...
- URL跳转的几种方式
1.HTML: ①. <head> <!-- 以下方式只是刷新不跳转到其他页面 --> <meta http-equiv="refresh" cont ...