DevExpress.XtraTreeList


1. DevExpress.XtraTreeList控件
        將其簡稱為tree,tree其實就是一個樹表控件,他像樹一樣包含具有父子關系的若干節點,同時每個節點又是一個帶有多個字段的記錄。其用法非常簡單方便,只需要為其配置帶有父子關系的數據源,其就可以按照樹的形式進行顯示。
1.1 DevExpress.XtraTreeList配置數據源
   數據源一般是一個二維表,可以是數據庫中的表,該表中要包含表示父子關系的兩個字段,即主鍵和父親的主鍵。下面的代碼是手動創建的數據源DataTable。

C# code ?
1
2
3
4
5
6
7
8
9
10
11
DataTable dtAllPath =  new  DataTable( "dtAllPath" );
             dtAllPath.Columns.Add( "nodeID" typeof ( int ));
             dtAllPath.Columns.Add( "parNodeID" typeof ( int )); 
             dtAllPath.Columns.Add( "stateName" typeof ( string ));
             dtAllPath.Columns.Add( "stateCode" typeof ( string ));
             dtAllPath.Columns.Add( "condition" typeof ( string ));
             dtAllPath.Rows.Add( new  object [] { 1, 0,  "1" "1" ""  });
dtAllPath.Rows.Add( new  object [] { 2, 0,  "2" "2" ""  });
dtAllPath.Rows.Add( new  object [] { 3, 1,  "1.1" "1.1" ""  });
dtAllPath.Rows.Add( new  object [] { 4, 2,  "2.1" "2.1" ""  });
treeList1.DataSource = dtAllPath;


上面的代碼中,nodeID是每行記錄的主鍵,parNodeID是每行記錄的父親記錄的主鍵,0表示樹的根結點。最后一行代碼是將生成的數據源交給 tree顯示。當然為了完成樹的顯示工作,還需要配置tree的KeyFieldName屬性為nodeID,ParentFieldName屬性為 parNodeID(選中tree,在vs的屬性窗口設置),還需要為tree添加列並配置該列與數據源中的字段對應關系,右鍵tree控件選擇 run designer彈出下圖,FieldName用來配置對應關系,tree中添加了兩列,第一列和stateCode對應,designer可以 配置tree的各種屬性,列標題,cell中的字體顏色等等,不再一一贅述。

1.2 DevExpress.XtraTreeList添加checkbox
   在tree的結點中添加checkbox是一項非常實用常見的功能,設置起來非常簡單,選中tree,在VS的屬性窗口中,找到OptionsView\ShowCheckBoxes,將其設置為true,即可。
1.3 DevExpress.XtraTreeList列表中添加ComboBox
  在tree控件中直接對信息進行編輯,有時可能需要用到ComboBox控件,具體添加方法,右鍵/run designer/選擇列 /ColumnEdit/New,為該列創建一個內嵌的ComboBox控件,即repositoryItemComboBox,具體如下圖所示。
 
1.4 repositoryItemComboBox下拉表不能顯示
  通過repositoryItemComboBox的click事件,向其動態add下拉列表中的items后,點擊 repositoryItemComboBox的下拉按鈕,下拉列表閃一下就消失了(不是在click事件中添加items的情況,不會出現此問題)。解 決方案,在repositoryItemComboBox的ButtonClick事件中,將事件源sender轉換為ComboBoxEdit,再利用 add函數添加item,最后手動顯示下拉列表,代碼如下:
ComboBoxEdit combo = sender as ComboBoxEdit;            combo.Properties.Items.Add(…);
combo.ShowPopup();

1.5 DevExpress.XtraTreeList設置焦點函數setFocusedNode()無效
   當使用TreeListNode addedNode = treeList1.AppendNode(參數略),向tree中添加一個節點后,一 般想立刻使這個新添加的節點獲得焦點,但此時如果直接使用treeList1.SetFocusedNode(addedNode)則無效,可能是因為 addedNode中不包含tree為其分配的nodeID(猜測),解決方案是 treeList1.SetFocusedNode(treeList1.FindNodeByKeyID(stateID));即利用findnode 之類的函數去查詢tree,找到新添加的結點,在將該節點作為SetFocusedNode的參數,則可以完成焦點的設置。
1.6 DevExpress.XtraTreeList查找結點函數FindNodeByKeyID()無效
  tree的find這類函數,在進行查找時,需要注意參數的類型,例如,這個函數FindNodeByKeyID()是根據數據源里的主鍵進行結點查 找,即你需要給定tree對應數據源中的記錄的key,如果數據源中的key是整型,而我們利用一個字符串類型作為參數的 話, FindNodeByKeyID(”100”)將不能找到節點,正確的寫法應該是FindNodeByKeyID(100)。
1.7 DevExpress.XtraTreeList部分結點添加checkbox或者圖片
   有些時候,不想在所有節點前都添加checkbox或者想在結點前添加圖片,此時需要手動添加事件CustomDrawNodeCheckBox的 處理函數,在函數中為某些結點定制checkbox,或者圖片,本處只着重說明定制checkbox,關於結點圖片的代碼可以參考網址 https://www.devexpress.com/Support/Center/Question/Details/Q142494。上碼,上 圖,如下:

C# code ?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
private  void  treeList2_CustomDrawNodeCheckBox( object  sender, DevExpress.XtraTreeList.CustomDrawNodeCheckBoxEventArgs e)
         {
             String variID = e.Node.GetValue( "variID" ).ToString(); //e.Node為tree的結點
             //滿足該條件的結點,為其設置checkbox,其他結點沒有checkbox
             if  (variID ==  "" )
             {
                 DevExpress.XtraTreeList.ViewInfo.IndentInfo ii = treeList2.ViewInfo.RowsInfo[e.Node].IndentInfo;
                 int  x2 = e.Bounds.Left + ii.LevelWidth / 2;
                 int  y2 = e.Bounds.Top + e.Bounds.Height / 2;
                 int  h2 = e.Bounds.Height / 2 + 1;
                 Rectangle r1 =  new  Rectangle(e.Bounds.Left, y2, e.Bounds.Width, 1);
                 Rectangle r2 =  new  Rectangle(x2, y2, 1, h2);
                 e.Graphics.FillRectangle(treeList2.ViewInfo.RC.TreeLineBrush, r1);
                 if  (e.Node.Expanded)
                 {
                     e.Graphics.FillRectangle(treeList2.ViewInfo.RC.TreeLineBrush, r2);
                 }
                 e.Handled =  true ;
             }
         }


 

在最近的工作中,使用到了DevExpress中的XtraTreeList用法,正好借此機會研究一下此控件的應用,現將其應用技巧與大家分享一下。

1、使用XtraTreeList綁定數據(數據格式可以為ArrayList形式)

我們實例說明要實現下面樣式的窗體:

首先,在Run Designer里面添加兩個列(columns),設置兩列的屬性,其中第一列“名稱”為string格式,FieldName為Name;第二列“選 擇”將ColumnEdit屬性設置為CheckEdit1,FieldName為IsChecked,設置完畢。

其次可以編寫一個類,用來綁定TreeList,針對此TreeList窗體,其類代碼設置如下:

public class TestTreeList

    {

        public TestTreeList()

        {

        }

        //名稱字段變量

        private string m_sName = string.Empty;

        //選擇字段變量

        private bool m_bIsChecked = false;

        //子Node節點ID變量

        private int m_iID = -1;

        //父Node節點ID變量

        private int m_iParentID = -1;

 

        public int ID

        {

            get

            {

                return m_iID;

            }

            set

            {

                m_iID = value;

            }

        }

        public int ParentID

        {

            get

            {

                return m_iParentID;

            }

            set

            {

                m_iParentID = value;

            }

        }

        public string Name

        {

            get

            {

                return m_sName;

            }

            set

            {

                m_sName = value;

            }

        }

 

        public bool IsChecked

        {

            get

            {

                return m_bIsChecked;

            }

            set

            {

                m_bIsChecked = value;

            }

        }

}

類構造完成,在FormLoad里面借助此類對TreeList進行綁定:

  private void Form1_Load(object sender, EventArgs e)

        {

            ArrayList pList = new ArrayList();

            TestTreeList p = new TestTreeList();

            p.Name = "測試1";

            p.IsChecked = true;

            p.ID = 1;

            pList.Add(p);

            TestTreeList q = new TestTreeList();

            q.Name = "測試2";

            q.IsChecked = false;

            q.ParentID = 1;

            q.ID = 2;

            pList.Add(q);

            this.treeList1.DataSource = pList;

            this.treeList1.RefreshDataSource();

 

        }

這樣就可以構造出一個簡單的TreeList應用方法,程序運行結果可得第一幅圖所示。

2、DevTreeList改變樣式:

如果將TreeList控件改變成如下樣式(同第一幅圖不一樣,將Check控件顯示在節點最前面)。

 

可以直接修改其控件的ShowCheckBoxes屬性即可(其它樣式類似如下)。

 

3、DevTreeList非綁定形式實現:動態加載,構建:

運行樣式如下:

 

實現動態加載的幾個函數實現如下:

/// <summary>

        /// 動態創建TreeList的Column,一列為圖層名,一列為是否統計列Check控件

        /// </summary>

        private void creatTreeListControl()

        {

            DevExpress.XtraTreeList.Columns.TreeListColumn treeListColumnLayerName= new DevExpress.XtraTreeList.Columns.TreeListColumn();

            treeListColumnLayerName.Caption = "名稱";

            treeListColumnLayerName.FieldName = "LayerName";

            treeListColumnLayerName.MinWidth = 38;

            treeListColumnLayerName.Name = "treeListColumnLayerName";

            treeListColumnLayerName.Visible = true;

            treeListColumnLayerName.VisibleIndex = 0;

            treeListColumnLayerName.Width = 111;

 

            DevExpress.XtraTreeList.Columns.TreeListColumn treeListColumnStatisticValue=new DevExpress.XtraTreeList.Columns.TreeListColumn();

              treeListColumnStatisticValue.Caption = "統計值";

            treeListColumnStatisticValue.ColumnEdit = this.repositoryItemCheckEdit1;

            treeListColumnStatisticValue.FieldName = "StatisticValue";

            treeListColumnStatisticValue.Name = "treeListColumnStatisticValue";

            treeListColumnStatisticValue.Visible = true;

            treeListColumnStatisticValue.VisibleIndex = 1;

 

            this.treeListLayerControl.Columns.AddRange(new DevExpress.XtraTreeList.Columns.TreeListColumn[] {

            treeListColumnLayerName,

            treeListColumnStatisticValue});

            this.treeListLayerControl.Nodes.Clear();

            this.treeListLayerControl.Refresh();

 

        }

/// <summary>

        /// 動態創建TreeList Layer Node節點

        /// </summary>

        /// <param name="layerName"></param>

        /// <param name="check"></param>

        private void creatMainLayerNode(string layerName,bool check)

        {

            this.treeListLayerControl.BeginUnboundLoad();

            this.treeListLayerControl.AppendNode(new object[] {  layerName,check}, -1);

            this.treeListLayerControl.EndUnboundLoad();

        }

    /// <summary>

        /// 動態創建TreeList 字段屬性值 Node節點

        /// </summary>

        /// <param name="ValueName"></param>

        /// <param name="check"></param>

        /// <param name="ID"></param>

        private void CreatChildNode(string ValueName, bool check,int ID)

        {

            this.treeListLayerControl.BeginUnboundLoad();

            this.treeListLayerControl.AppendNode(new object[] { ValueName, check }, ID);

            this.treeListLayerControl.EndUnboundLoad();

        }

  /// <summary>

        /// 獲得圖層名節點的Index值

        /// </summary>

        /// <param name="ParentNodeName"></param>

        /// <returns></returns>

        private int getParentID(string ParentNodeName)

        {

            int i = -1;

            for (i = 0; i < this.treeListLayerControl.Nodes.Count;i++ )

            {

                if (this.treeListLayerControl.Nodes[i][0].ToString() == ParentNodeName)

                {                 

                    break;

                }

 

            }

            return i;

 

        }

    /// <summary>

        /// 當點擊Node事件發生改變(點擊主節點時,其子節點跟着主節點變化)

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void treeListLayerControl_CellValueChanging(object sender, DevExpress.XtraTreeList.CellValueChangedEventArgs e)

        {

            if (e.Column.Name.Equals("treeListColumnStatisticValue") && e.Node.HasChildren)

            {

                object objCol = this.treeListLayerControl.Columns[1];

                for (int i = 0; i < e.Node.Nodes.Count; i++)

                {

                    e.Node.Nodes[i].SetValue(objCol, e.Value);

                }

                e.Node.SetValue(objCol, e.Value);

            }

        }

創建子節點方法:

      int indexLayerTree = this.getParentID(playerInfo.LayerName);

                    if (indexLayerTree == -1)

                        return;

                    CreatChildNode(sValue, false, this.treeListLayerControl.Nodes[indexLayerTree].Id);

其創建主節點和創建子節點方法類似,比創建子節點簡單的多。

4、總結

以上為個人研究DevExpress TreeList使用的大致方法,盡管文筆簡單潦草,但是針對TreeList的基本使用足矣。

另外,DevExpress控件可以使系統界面做的十分漂亮,我的截圖界面顯得丑陋,只因為是實驗程序,並不是真正應用,還請大家不要誤解。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM