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

1 篇文章 0 订阅
1 篇文章 0 订阅

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

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

TreeList的重要属性

关于绑定数据的属性

在TreeList中,绑定数据时有两个重要的基本属性:KeyFieldName,以及ParentFieldName。通过这两个基本属性的设置,即可实现层级结构显示。
TreeList属性
在KeyFieldName以及ParentFieldName中分别绑定相应的数据表字段名
数据库设计及其数据如下图:
数据库设计
表中的数据
绑定数据库的操作方法在后面再详细讲解。

关于显示CheckBox的属性

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

关于Checkbox显示3种选中状态

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

关于设置TreeList是否可编辑

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

显示CheckBox的三种选中状态

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);
    }
}

获取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);
        }
    }                     
}

当需要获取到当前所选取的节点时,直接在相应时间中调用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;
}

通过以上方法可以获得相应的所有的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);
    }
}
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值