作为一个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 树形控件 的操作的更多相关文章

  1. Devexpress treelist 树形控件 实现带三种状态的CheckBox

    树形控件是使用频率很高的一种控件.对于属性控件往往需要下面两个功能 1.TreeList带有CheckBox,并且节点要有三种状态(所有的子节点都选中,所有的子节点都没选择,一部分子节点选中).使用 ...

  2. Visual studio C++ MFC之树形控件Tree Control

    背景 本篇旨在MSDN帮助文档下总结树形控件Tree Control的使用,并列出碰到的具体问题. 正文 树形控件Tree Control的类则是CTreeCtrl,具体成员对象详见链接,以下则描述一 ...

  3. 在DevExpress中使用CameraControl控件进行摄像头图像采集

    在我们以前的项目了,做摄像头的图片采集,我们一般还是需要做一个封装处理的,在较新版本的DevExpress控件里面,增加了一个CameraControl控件,可以直接调用摄像头显示的,因此也可以做头像 ...

  4. js树形控件—zTree使用总结

    0 zTree简介 树形控件的使用是应用开发过程中必不可少的.zTree 是一个依靠 jQuery 实现的多功能 “树插件”.优异的性能.灵活的配置.多种功能的组合是 zTree 最大优点. 0.0 ...

  5. 基于Bootstrap的JQuery TreeView树形控件,数据支持json字符串、list集合(MVC5)<二>

    上篇博客给大家介绍了基于Bootstrap的JQuery TreeView树形控件,数据支持json字符串.list集合(MVC5)<一>, 其中的两种方式都显得有些冗余.接着上篇博客继续 ...

  6. 在DevExpress中使用WizardControl控件构建多步向导界面

    利用好的界面控件,往往能做成比较界面体验效果.在一些界面操作里面,我们可能把它拆分为几部进行处理,这个时候引入WizardControl向导控件应该是比较不错的选择了.多步的处理方式,可以让用户避免一 ...

  7. DevExpress winform XtraEditor常用控件

    最近在公司里面开始使用DevExpress winform的第三方控件进行开发和维护,这里整理一些常用控件的资料以便于后续查看 ComboBoxEdit 这个控件和winform自带的控件差不多,使用 ...

  8. js树形控件

    js树形控件 ztree http://www.treejs.cn/

  9. TreeView树形控件递归绑定数据库里的数据

    TreeView树形控件递归绑定数据库里的数据. 第一种:性能不好 第一步:数据库中查出来的表,字段名分别为UNAME(显示名称),DID(关联数据),UTYPE(类型) 第二步:前台代码 <% ...

随机推荐

  1. C# Extension Methods

    In C#, extension methods enable you to add methods to existing class without creating a new derived ...

  2. Python模块应用 (linecache)

    linecache linecache是专门支持读取大文件,而且支持行式读取的函数库. linecache 预先把文件读入缓存起来,后面如果你访问该文件的话就不再从硬盘读取.对于大文件的读取效率还不错 ...

  3. ubuntu安装node.js+express+mongodb

    输入以下命令安装: sudo apt-get install nodejs 安装完成后,终端输入nodejs,就能进入node命令啦: 但是正常下应该是输入node进入命令而不是nodejs: 在Ub ...

  4. Art-template模板

    1.介绍 新一代 javascript 模板引擎. 2.性能(引) 1.性能卓越,执行速度通常是 Mustache 与 tmpl 的 20 多倍(性能测试) 2.支持运行时调试,可精确定位异常模板所在 ...

  5. Android Studio 使用Lambda

    1,昨天在使用RxJava的时候,调用map.filter之类的方法要创建挺多的匿名内部类,所以我们打算试用一下Lambda让我们的代码更有阅读新性,下看一下我们的对比 在使用之前我们代码是这样的 O ...

  6. logstash读取redis数据

    类型设置: logstash中的redis插件,指定了三种方式来读取redis队列中的信息. list=>BLPOP                                    (相当 ...

  7. python学习笔记系列----(六)错误和异常

    python至少有2类不同的错误:语法错误(Syntax Errors)和异常(Exceptions). 8.1 语法错误 这个单词应该还是很有必要认识的,呵呵,语法错误,也叫解析错误,是我们最不愿意 ...

  8. Swift

    1.Swift项目与OC项目的区别 - Swift的类文件是以 .swift 结尾 - main.m 不见了,程序入口以 `@UIApplicationMain` - Swift中,代码都是写到 `{ ...

  9. 推荐一篇好文:OSG OSGearth vs2010编译

    链接:http://weibo.com/p/2304189447a8480102v2c2 此文作者把用到的相关代码包放在:http://pan.baidu.com/s/1qW9a4zU 按照步骤操作完 ...

  10. python之编写购物车(第二天)

    作业: 编写购物车 具体实现了如下功能: 1.可购买的商品信息显示 2.显示购物车内的商品信息.数量.总金额 3.购物车内的商品数量进行增加.减少和商品的删除 4.用户余额的充值 5.用户购买完成进行 ...