详解在DevExpress程序中使用TreeList控件以及节点查询的处理

在很多情况下,我们需要通过树列表进行数据的展示,如一些有层次关系的数据,通过有层级的展示,能够使用户更加直观查看和管理相关的数据。在一般Winform开发的情况下,可以使用微软的TreeView控件,也可以使用DevExpress的TreeList控件进行数据的展示,本篇随笔主要介绍基于DevExpress的TreeList控件使用以及使用SearchControl对节点进行查询的操作。

1、 使用微软的TreeView控件的实现效果和思路

在很多情况下,我们也倾向于使用TreeView控件作为数据的展示,相对于TreeList控件,这种控件的处理,需要自己管理树节点的层次关系,不过使用也比较简单,呈现的效果两者都差别不大。

如在我开发框架中,在字典管理模块里面,就是采用这个控件进行数据的展示的,整体效果也还不错。

在树形列表里面,我们获取数据后,统一根据层级的关系构建树节点即可,如下代码所示。

/// <summary>
/// 初始化树信息
/// </summary>
private void InitTreeView()
{
  this.treeView1.Nodes.Clear();
  this.treeView1.BeginUpdate();
  List<DictTypeNodeInfo> typeNodeList = BLLFactory<DictType>.Instance.GetTree();
  foreach (DictTypeNodeInfo info in typeNodeList)
  {
    AddTree(null, info);
  }
  this.treeView1.EndUpdate();
  this.treeView1.ExpandAll();
}
/// <summary>
/// 根据节点数据,递归构建该层级以下的树节点
/// </summary>
/// <param name="pNode">父树节点</param>
/// <param name="info">字典类型数据</param>
private void AddTree(TreeNode pNode, DictTypeNodeInfo info)
{
  TreeNode node = null;
  if (info.PID == "-1")
  {
    node = new TreeNode(info.Name, 0, 0);
    node.Tag = info.ID;
    this.treeView1.Nodes.Add(node);
  }
  else
  {
    node = new TreeNode(info.Name, 1, 1);
    node.Tag = info.ID;
    pNode.Nodes.Add(node);
  }
  foreach (DictTypeNodeInfo subInfo in info.Children)
  {
    AddTree(node, subInfo);
  }
}

还有我们在鼠标选择某个节点的时候,触发AfterSelect事件,这样我们就可以处理鼠标节点的事件了

/// <summary>
/// 单击节点事件处理
/// </summary>
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
  if (e.Node.Tag != null)
  {
    this.lblDictType.Text = e.Node.Text;
    this.lblDictType.Tag = e.Node.Tag;
    BindData();
  }
}

以上就是使用TreeView控件来处理数据的展示,从上面代码可以看到,整体的内容,主要是通过递归的关系来构建TreeNode的处理,但是使用的代码也不算复杂,因此大多数可以采用这种方式来自定义树形节点的展示。

2、使用DevExpress的TreeList控件的效果和实现代码

而使用DevExpress的TeeList控件,可以通过KeyFieldName和ParentFieldName指定他们的层级关系,使用就更加简单化,提供的数据源会自动进行层次的关系处理,非常方便。

我们先来看看通过DevExpress的TreeList控件展示的字典类型和字典数据的界面效果。

这里面的效果是如何通过代码实现的呢?

首先我们使用代码获取字典类型数据并进行树列表控件的初始化操作,如下所示。

//添加显示列
this.tree.Columns.Add(new TreeListColumn{ FieldName= "Name", Caption= "字典类型名称", Width=160, VisibleIndex =0});
//设置树控件的层次关系及属性
tree.KeyFieldName = "ID";
tree.ParentFieldName = "PID";
this.tree.OptionsBehavior.Editable = false;
this.tree.OptionsView.EnableAppearanceOddRow = true;
this.tree.OptionsView.EnableAppearanceEvenRow = true;

上面的代码我们还可以通过扩展函数对树列表的处理进行封装,已达到简化代码的目的,如下是处理后的实现代码:

//控件扩展函数封装处理
this.tree.CreateColumn("Name", "字典类型名称", 160, true);
this.tree.InitTree("ID", "PID", "-1", false, false);

通过添加TreeListColumn对象给TreeList控件就可以实现字段列的显示了,同时指定数据源里面的KeyFieldName和ParentFieldName来设定层级关系即可,非常简单。

而绑定数据源,则可以通过一个函数进行处理,如下所示。

/// <summary>
/// 绑定树的数据源
/// </summary>
private void BindTree()
{
  this.tree.DataSource = BLLFactory<DictType>.Instance.GetAll();
  this.tree.ExpandAll();
}

从上面代码我们可以看到,我们返回的数据源,不需要在实体类对象层级具有上下级的关系,如通过TreeView实现的时候,我们使用了DictTypeNodeInfo 对象是具有上下层级关系的。

这里只需要使用普通的DictTypeInfo 对象集合即可,通过KeyFieldName和ParentFieldName来设定层级关系即可。

为了指定树形节点的图标,我们可以通过代码进行自定义图标的处理,如下代码所示,这样每个层级的图标都不一样,自动实现获取设置的处理。

//设置树的图标集合及逐级图标
this.tree.SelectImageList = this.imageCollection1;
this.tree.CustomDrawNodeImages += (object sender, CustomDrawNodeImagesEventArgs e)=>
{
  int maxCount = this.imageCollection1.Images.Count;
  var index = e.Node.Level < maxCount ? e.Node.Level : 0;
  e.SelectImageIndex = index;
};

实现树节点选中的事件处理,则需要实现FocusedNodeChanged事件即可。

//初始化树节点选择事件
  this.tree.FocusedNodeChanged += delegate(object sender, FocusedNodeChangedEventArgs e)
  {
    this.FocusedNodeChanged();
  };
}
private void FocusedNodeChanged()
{
  if (this.tree.FocusedNode != null)
  {
    var PID = string.Concat(this.tree.FocusedNode.GetValue("ID"));
    treeConditionSql = string.Format("DictType_ID = '{0}'", PID);
  }
  else
  {
    treeConditionSql = "";
  }
  BindData();
}

最后初始化树列表的代码如下所示。

private void InitTree()
{
  this.tree.Columns.Clear();
  //控件扩展函数封装处理
  this.tree.CreateColumn("Name", "字典类型名称", 160, true);
  this.tree.InitTree("ID", "PID", "-1", false, false);
  //设置树的图标集合及逐级图标
  this.tree.SelectImageList = this.imageCollection1;
  this.tree.CustomDrawNodeImages += (object sender, CustomDrawNodeImagesEventArgs e)=>
  {
    int maxCount = this.imageCollection1.Images.Count;
    var index = e.Node.Level < maxCount ? e.Node.Level : 0;
    e.SelectImageIndex = index;
  };
}

3、基于SearchControl控件对节点进行查询的操作

上面的处理就是树列表的一般性展示,如果需要在树节点上面增加一个查询过滤的操作,那么可以使用SearchControl控件进行过滤处理,只需要设置SearchControl控件的Client属性,以及实现树控件的FilterNode事件即可。

/// <summary>
/// 实现树节点的过滤查询
/// </summary>
private void InitSearchControl()
{
  this.searchControl1.Client = this.tree;
  this.tree.FilterNode += (object sender, DevExpress.XtraTreeList.FilterNodeEventArgs e) =>
  {
    if (tree.DataSource == null)
      return;
    string nodeText = e.Node.GetDisplayText("Name");//参数填写FieldName
    if (string.IsNullOrWhiteSpace(nodeText))
      return;
    bool isExist = nodeText.IndexOf(searchControl1.Text, StringComparison.OrdinalIgnoreCase) >= 0;
    if (isExist)
    {
      var node = e.Node.ParentNode;
      while (node != null)
      {
        if (!node.Visible)
        {
          node.Visible = true;
          node = node.ParentNode;
        }
        else
          break;
      }
    }
    e.Node.Visible = isExist;
    e.Handled = true;
  };
}

实现效果如下所示, 对于符合记录的查询,那么会有高亮的颜色进行重点标注。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持我们!

(0)

相关推荐

  • DevExpress实现TreeList节点互斥的方法

    本文实例讲述了DevExpress实现TreeList节点互斥的方法,具体实现方法如下所示: 主要功能代码如下: /// <summary> /// 节点互斥同步 /// 说明 /// eg: ///TreeListNode _node = e.Node; ///_node.SyncMutexNodeCheckState(_node.CheckState, n => n.GetNodeType() == NodeType.Cab); /// </summary> /// &l

  • DevExpress实现TreeList父子节点CheckState状态同步的方法

    本文实例展示了DevExpress实现TreeList父子节点CheckState状态同步的方法,在项目开发中有一定的应用价值,具体实现方法如下: 主要功能代码如下: /// <summary> ///同步父子节点勾选状态 ///说明 ///在AfterCheckNode事件中使用代码 ///eg:e.Node.SyncNodeCheckState(e.Node.CheckState); /// </summary> /// <param name="node&qu

  • DevExpress设置TreeList图片节点背景色的方法

    本文实例展示了DevExpress设置TreeList图片节点背景色的方法,在项目开发中有一定的应用价值,具体方法如下所示: 主要功能代码如下: /// <summary> /// 设置图片节点的背景色 /// 说明:在CustomDrawNodeImages事件中使用 /// </summary> /// <param name="tree">TreeList</param> /// <param name="e&quo

  • DevExpress实现TreeList按条件隐藏节点CheckBox的方法

    本文实例讲述了DevExpress实现TreeList按条件隐藏节点CheckBox的方法,在项目开发中有一定的使用价值.具体的实现方法如下: 主要功能代码如下: /// <summary> /// 隐藏CheckBox /// 说明 /// 在CustomDrawNodeCheckBox事件中使用 /// eg: /// TreeList _curTree = (TreeList)sender; /// _curTree.HideCheckBox(n => n.GetNodeType(

  • DevExpress获取TreeList可视区域节点集合的实现方法

    本文实例展示了DevExpress获取TreeList可视区域节点集合的实现方法,是比较有实用价值的技巧.分享给大家供大家参考.具体实现方法如下: 关键代码如下: /// <summary> /// 获取可视区域节点 /// </summary> /// <param name="treeList">TreeList</param> /// <param name="conditonHanlder">条件委

  • DevExpress实现TreeList向上递归获取符合条件的父节点

    本文实例展示了DevExpress实现TreeList向上递归获取符合条件的父节点的方法,在一些项目开发中比较有实用价值,具体实现方法如下所示: 主要功能代码如下: /// <summary> /// 向上递归,获取符合条件的父节点 /// </summary> /// <param name="node">需要向上递归的节点</param> /// <param name="conditionHanlder"&

  • DevExpress实现TreeList向上递归获取公共父节点的方法

    有时候在进行C#项目开发中,需要获取到公共节点,如下图所示: 譬如,当点击"Test103-2"节点,其类型是"灯"类型,那怎么获取到"中心区域"这个类型是"地域"的公共节点?对此具体实现方法如下: 主要功能代码如下: /// <summary> /// 向上递归,获取符合条件的父节点 /// </summary> /// <param name="node">需要向上递

  • 详解在DevExpress程序中使用TreeList控件以及节点查询的处理

    在很多情况下,我们需要通过树列表进行数据的展示,如一些有层次关系的数据,通过有层级的展示,能够使用户更加直观查看和管理相关的数据.在一般Winform开发的情况下,可以使用微软的TreeView控件,也可以使用DevExpress的TreeList控件进行数据的展示,本篇随笔主要介绍基于DevExpress的TreeList控件使用以及使用SearchControl对节点进行查询的操作. 1. 使用微软的TreeView控件的实现效果和思路 在很多情况下,我们也倾向于使用TreeView控件作为

  • 详解微信小程序中的页面代码中的模板的封装

    详解微信小程序中的页面代码中的模板的封装 最近在进行微信小程序中的页面开发,其实在c++或者说是js中都会出现这种情况,就是相同的代码会反复出现,这就是进行一定的封装,封装的好处就是可以是程序中在于减少一定的代码量,并且可是使代码结构更加清晰.那今天所要记录的就是关于微信小程序中的页面的模板封装. 在微信小程序中的文件名都带有wxml等样式,在wxml中提供了模板,即可以在模板中定义代码片段,然后可以在页面中的不同位置进行调用,模板的定义: <templatename="products&

  • 详解Android 裸眼3D效果View控件

    描述:这是一个裸眼3D效果的控件View. Tips:本项目代码部分逻辑参考于其他文章(自如的3D裸眼实现),众人拾柴火焰高,希望大家能多多补充. 项目代码:https://gitee.com/jiugeishere/uidesign 控件效果如下: 实现功能: 实现三层图片叠加效果(裸眼3D效果) 可设置每层图片移动速率 可设置每层图片移动的限制度数 可直接设置图片或引入图片 设计核心: 主要的设计核心是依赖于传感器对手机晃动的监听(重力感应监听器),对每层图片进行不同的移动,实现仿3D效果.

  • 详解在Java程序中运用Redis缓存对象的方法

    这段时间一直有人问如何在Redis中缓存Java中的List 集合数据,其实很简单,常用的方式有两种: 1. 利用序列化,把对象序列化成二进制格式,Redis 提供了 相关API方法存储二进制,取数据时再反序列化回来,转换成对象. 2. 利用 Json与java对象之间可以相互转换的方式进行存值和取值. 正面针对这两种方法,特意写了一个工具类,来实现数据的存取功能. 1. 首页在Spring框架中配置 JedisPool 连接池对象,此对象可以创建 Redis的连接 Jedis对象.当然,必须导

  • 详解mpvue小程序中怎么引入iconfont字体图标

    前言 iconfont阿里巴巴矢量图标库是我很喜欢的一个网站,可以下载/在线编辑/上传自己需要的矢量图标,也支持团队协作,那么在mpvue项目中如何引入呢? iconfont阿里巴巴矢量图标库 将图标加入购物车 搜索关键词可以是中文也可以是英文 下载素材 点击网站右上角的购物车图标,此处我们选第三个 ps:添加到项目很有用,可以在线编辑自己喜欢的图标大小样式/重命名/邀请成员等,此处我们选择加入项目并下载代码 文件解压 一般网页中为了兼容性考虑,我们会留下css/ttf/svg/woff/eot

  • 详解解决小程序中webview页面多层history返回问题

    小程序开发中遇到的问题:小程序中嵌套了一个webview页面,webview页面中有静默授权(A1页面静默授权后重定向到A2页面),点小程序原生的返回按钮会返回到A1页面,然后页面就会反复静默授权 预期表现:点小程序原生的返回按钮后返回到小程序上个页面 解决方案:通过history.pushState添加历史记录名目,history.onpopstate监听历史记录条目发生变化时,调用小程序APIwx.navigateBack window.addEventListener('popstate'

  • 详解微信小程序中var、let、const用法与区别

    微信小程序可以使用Javascript的最新ES6标准来开发所以微信小程序中var.let.const用法与区别可以视为Javascript ES6标准中var.let.const用法与区别 let命令 基本用法 ES6 新增了let命令,用来声明变量.它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效. { let a = 10; var b = 1; } a // ReferenceError: a is not defined. b // 1 上面代码在代码块之中,分

  • 详解在Python程序中自定义异常的方法

    通过创建一个新的异常类,程序可以命名它们自己的异常.异常应该是典型的继承自Exception类,通过直接或间接的方式. 以下为与RuntimeError相关的实例,实例中创建了一个类,基类为RuntimeError,用于在异常触发时输出更多的信息. 在try语句块中,用户自定义的异常后执行except块语句,变量 e 是用于创建Networkerror类的实例. class Networkerror(RuntimeError): def __init__(self, arg): self.arg

  • 详解在Python程序中使用Cookie的教程

    大家好哈,上一节我们研究了一下爬虫的异常处理问题,那么接下来我们一起来看一下Cookie的使用. 为什么要使用Cookie呢? Cookie,指某些网站为了辨别用户身份.进行session跟踪而储存在用户本地终端上的数据(通常经过加密) 比如说有些网站需要登录后才能访问某个页面,在登录之前,你想抓取某个页面内容是不允许的.那么我们可以利用Urllib2库保存我们登录的Cookie,然后再抓取其他页面就达到目的了. 在此之前呢,我们必须先介绍一个opener的概念. 1.Opener 当你获取一个

  • 详解在Python程序中解析并修改XML内容的方法

    需求 在实际应用中,需要对xml配置文件进行实时修改, 1.增加.删除 某些节点 2.增加,删除,修改某个节点下的某些属性 3.增加,删除,修改某些节点的文本 使用xml文档 <?xml version="1.0" encoding="UTF-8"?> <framework> <processers> <processer name="AProcesser" file="lib64/A.so&q

随机推荐