在很多情况下,我们需要通过树列表进行数据的展示,如一些有层次关系的数据,通过有层级的展示,能够使用户更加直观查看和管理相关的数据。在一般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 "htmlcode">//初始化树节点选择事件 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 "htmlcode">/// <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; }; }实现效果如下所示, 对于符合记录的查询,那么会有高亮的颜色进行重点标注。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 【雨果唱片】中国管弦乐《鹿回头》WAV
- APM亚流新世代《一起冒险》[FLAC/分轨][106.77MB]
- 崔健《飞狗》律冻文化[WAV+CUE][1.1G]
- 罗志祥《舞状元 (Explicit)》[320K/MP3][66.77MB]
- 尤雅.1997-幽雅精粹2CD【南方】【WAV+CUE】
- 张惠妹.2007-STAR(引进版)【EMI百代】【WAV+CUE】
- 群星.2008-LOVE情歌集VOL.8【正东】【WAV+CUE】
- 罗志祥《舞状元 (Explicit)》[FLAC/分轨][360.76MB]
- Tank《我不伟大,至少我能改变我。》[320K/MP3][160.41MB]
- Tank《我不伟大,至少我能改变我。》[FLAC/分轨][236.89MB]
- CD圣经推荐-夏韶声《谙2》SACD-ISO
- 钟镇涛-《百分百钟镇涛》首批限量版SACD-ISO
- 群星《继续微笑致敬许冠杰》[低速原抓WAV+CUE]
- 潘秀琼.2003-国语难忘金曲珍藏集【皇星全音】【WAV+CUE】
- 林东松.1997-2039玫瑰事件【宝丽金】【WAV+CUE】