打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
DevExpress.XtraTreeList.TreeList
userphoto

2017.04.19

关注

DevExpress.XtraTreeList.TreeList + Winform + Access2013 使用实例(一)

在WinForm开发过程中使用到了第三方控件DevExpress中的TreeList,为了方便大家以及后面的查阅,特此将开发过程中的一些经验写出来供大家参考,包括了TreeList的一些外观现实,节点获取,以及Access数据库的批量存储操作等。本文同时也参考了网上的一些资料,特此向大神们致敬!

TreeList的重要属性

关于绑定数据的属性

在TreeList中,绑定数据时有两个重要的基本属性:KeyFieldName,以及ParentFieldName。通过这两个基本属性的设置,即可实现层级结构显示。 

 
在KeyFieldName以及ParentFieldName中分别绑定相应的数据表字段名 
数据库设计及其数据如下图: 
 
 
绑定数据库的操作方法在后面再详细讲解。

关于显示CheckBox的属性

只需要设置OptionsView.ShowCheckBoxes = True即可

关于Checkbox显示3种选中状态

需要设置OptionsBehavior.AllowIndeterminateCheckState = True即可 
关于如何显示这三种选中状态,在后面详细讲解。

关于设置TreeList是否可编辑

有时候,我们并不希望在单击TreeList单元格的时候,出现单元格可以编辑的情况,此时就需要设置TreeList的可编辑属性了。设置方法为OptionsBehavior.Editable = False

显示CheckBox的三种选中状态

CheckBox的三种显示状态如下: 

 
其具体代码如下

private void treeList1_BeforeCheckNode(object sender, DevExpress.XtraTreeList.CheckNodeEventArgs e){  e.State = (e.PrevState == CheckState.Checked ? CheckState.Unchecked : CheckState.Checked);}private void treeList1_AfterCheckNode(object sender, DevExpress.XtraTreeList.NodeEventArgs e) {     SetCheckedChildNodes(e.Node, e.Node.CheckState);     SetCheckedParentNodes(e.Node, e.Node.CheckState); }/// <summary>/// 设置子节点的状态/// </summary>/// <param name="node"></param>/// <param name="check"></param>private void SetCheckedChildNodes(DevExpress.XtraTreeList.Nodes.TreeListNode node, CheckState check){    for (int i = 0; i < node.Nodes.Count; i++)    {        node.Nodes[i].CheckState = check;        SetCheckedChildNodes(node.Nodes[i], check);    }}/// <summary>/// 设置父节点的状态/// </summary>/// <param name="node"></param>/// <param name="check"></param>private void SetCheckedParentNodes(DevExpress.XtraTreeList.Nodes.TreeListNode node, CheckState check){    if (node.ParentNode != null)    {        bool b = false;        CheckState state;        for (int i = 0; i < node.ParentNode.Nodes.Count; i++)        {            state = (CheckState)node.ParentNode.Nodes[i].CheckState;            if (!check.Equals(state))            {                b = !b;                break;            }        }        node.ParentNode.CheckState = b ? CheckState.Indeterminate : check;        SetCheckedParentNodes(node.ParentNode, check);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

获取TreeList选中的节点

获取方法如下:

private List<string> lstCheckedKeyID = new List<string>();//选择KeyID集合/// <summary>/// 获取选择状态的数据主键ID集合/// </summary>/// <param name="parentNode">父级节点</param>private void GetCheckedKeyID(TreeListNode parentNode){    if (parentNode.Nodes.Count == 0)    {        return;//递归终止    }    foreach (TreeListNode node in parentNode.Nodes)    {        if (node.CheckState == CheckState.Checked)        {            DataRowView drv = treeList1.GetDataRecordByNode(node) as DataRowView;//关键代码,就是不知道是这样获取数据而纠结了很久(鬼知道可以转换为DataRowView啊)            if (drv != null)            {                string KeyFieldName = (string)drv["KeyFieldName"];                lstCheckedKeyID.Add(KeyFieldName);            }        }        GetCheckedKeyID(node);    }}/// <summary>/// 获取选中的节点/// </summary>/// <param name="tree"></param>private void findOrigin(DevExpress.XtraTreeList.TreeList tree){    this.lstCheckedKeyID.Clear();    if (tree.Nodes.Count > 0)    {        foreach (TreeListNode root in tree.Nodes)        {            GetCheckedKeyID(root);        }    }                     }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

当需要获取到当前所选取的节点时,直接在相应时间中调用findOrigin(treeList1);即可。 
当时使用这个方法的时候发现,获取的节点并不全。比如说,当前表中只有父节点,如在表中的俄罗斯,选中它,运行上述代码,并不能获取到其KeyFieldName;再比方说,选中了南京之后,只能获取到南京和江苏省的KeyFieldName,并不能获取到中国的KeyFieldName。

上述问题的解决方法之一

在获取到节点之后,将其及与之对应的层次结构存进数据表中。由于在上一段中获取的节点并不全面,所以 
我只能在另起炉灶获取到所有应该存储的节点。

/// <summary>/// 比较当前Key与已经存储的Key,不同则添加/// </summary>/// <param name="list"></param>/// <param name="strID"></param>private void getDistinctID(List<string> list, string strID){    if (!list.Contains(strID))    {        list.Add(strID);    }            }/// <summary>/// 获取当前集合中字符串长度的最大值/// </summary>/// <param name="list">集合</param>/// <returns></returns>private int getMaxLength(List<string> list){    int MaxLength=0;    foreach(string strID in list)    {        if(MaxLength<strID.Length)        {            MaxLength = strID.Length;        }    }    return MaxLength;}/// <summary>/// 找到当前所有需要保存的节点/// </summary>/// <param name="list"></param>/// <returns></returns>private List<string> getAllKeys(List<string> list){    List<string> MaxLengthList = new List<string>();    List<string> AllKeysList = new List<string>();    int MaxLength = getMaxLength(list);    if (MaxLength > 1)    {        //获得最长KeyFieldName        foreach(string strID in list)        {            if(strID.Length==MaxLength)            {                getDistinctID(MaxLengthList, strID);                getDistinctID(AllKeysList, strID);            }        }                  for(int i=0;i<MaxLengthList.Count;i++)        {            for(int j=1;j<MaxLength;j++)            {                getDistinctID(AllKeysList, MaxLengthList[i].Substring(0, j));            }        }    }    return AllKeysList;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65

通过以上方法可以获得相应的所有的KeyFieldName。

上述问题的解决方法之二

GetCheckedKeyID函数修改如下:

/// <summary>/// 获取选择状态的数据主键ID集合/// </summary>/// <param name="parentNode">父级节点</param>private void GetCheckedKeyID(TreeListNode parentNode){    if (parentNode.Nodes.Count == 0)    {        return;//递归终止    }    if(parentNode.CheckState!=CheckState.Unchecked)    {        DataRowView drv = treeList1.GetDataRecordByNode(parentNode) as DataRowView;        if (drv != null)        {            string KeyFieldName = (string)drv["KeyFieldName"];            if (!lstCheckedKeyID.Contains(KeyFieldName))            {                lstCheckedKeyID.Add(KeyFieldName);            }                            }                    }    foreach (TreeListNode node in parentNode.Nodes)    {        if (node.CheckState != CheckState.Unchecked)        {            DataRowView drv = treeList1.GetDataRecordByNode(node) as DataRowView;//关键代码,就是不知道是这样获取数据而纠结了很久(鬼知道可以转换为DataRowView啊)            if (drv != null)            {                string KeyFieldName = (string)drv["KeyFieldName"];                lstCheckedKeyID.Add(KeyFieldName);            }        }        GetCheckedKeyID(node);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
DevExpress TreeList使用心得
Developer Express之TreeList常用用法 - 堕落-追逐 - 博客园
DevExpress控件
C# DevExpress PopupContainerEdit 下拉树列表的应用(转)
ASP.NET TREEVIEW 使用方法(2) - yyf919 - 博客园
Winform开发框架之权限管理系统改进的经验总结(1)-TreeListLookupEdit控件的使用
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服