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

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);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章