作为一个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. 使用WKWebView遇到的坑

    苹果从iOS8开始推出了WKWebView,大有替换UIWebView的意思(尽管Xcode中还没给UIWebView标记过期版本),所以决定将项目进行适配,iOS8及以上版本,改用WKWebView ...

  2. Windows Server 2008 R2父域管理员与子域管理员相互登录访问

    一.问题: 父域创建的域管理员登录不了子域服务器,子域创建的域管理员登录不了父域服务器? 二.原因分析: 父域创建的域管理员是存在父域中,而子域创建的域管理员存在子域中,父域创建的管理员是不存在子域中 ...

  3. rplidar测试

    以下在虚拟机中完成的(ubuntu12.04-amd64-ros-exbot-h2-140520). 进入catkin_ws,下载代码: cd ~/catkin_ws/src/ git clone h ...

  4. php定时任务

    ignore_user_abort(); //关掉浏览器,PHP脚本也可以继续执行. set_time_limit(0); // 通过set_time_limit(0)可以让程序无限制的执行下去 代码 ...

  5. hasOwnProperty 递归 简单回调 链式调用

    1.hasOwnProperty 函数的返回值为Boolean类型.如果对象object具有名称为propertyName的属性,则返回true,否则返回false. function Box(){ ...

  6. WPF中弹出文件夹浏览对话框

    附一个共享目录正则表达式判断: bool result= System.Text.RegularExpressions.Regex.IsMatch("\\pc-test\share" ...

  7. Android touch 事件传递机制

    前言: (1)在自定义view的时候经常会遇到事件拦截处理,比如在侧滑菜单的时候,我们希望在侧滑菜单里面有listview控件,但是我们希望既能左右滑动又能上下滑动,这个时候就需要对触摸的touch事 ...

  8. jquery-2.0.0

    http://code.jquery.com/jquery-2.0.0.min.js (minified, for production) http://code.jquery.com/jquery- ...

  9. SetSysColors 修改系统颜色

    首先我们来看一下SetSysColors函数的原型: BOOL WINAPI SetSysColors( __in int cElements, //要改变的对象的数量 __in const INT* ...

  10. Windows Phone 五、配置存储

    基本存储形式 本地设置:ApplicationData.Current.LocalSettings 漫游设置:ApplicationData.Current.RoamingSettings 支持的数据 ...