1. 程式人生 > >DevExpress_常用控制元件16_TreeList

DevExpress_常用控制元件16_TreeList

2.4 TreeList控制元件

樹列表,該事件的AfterCheckNode事件是當選擇CheckBox時所觸發的事件;

示例程式碼: 

/// <summary>

    /// 實體類

    /// </summary>

    class PersonTo

    {

        public string Name

        {

            set;

            get;

        }

        public string Age

        {

            set;

            get;

        }



}

//繫結資料來源,新增節點

 private void AddTreeNode()

        {

            ArrayList pl = new ArrayList();

            PersonTo p = new PersonTo();

            p.Name = "liu";

            p.Age = "20";

            pl.Add(p);

            PersonTo p2 = new PersonTo();

            p2.Name = "yu";

            p2.Age = "21";

            pl.Add(p2);

            treeList1.DataSource=pl;

           object[] s = new object[] { "1", "1", "1" };

           object ss = new object();

           this.treeList1.AppendNode(s,0);

}

1、該控制元件下的OptionsView屬性下的ShowCheckBoxes屬性控制是否每項前顯示CheckBox,該屬性屬於bool型別

節點摺疊 this.treeList1.CollapseAll();

一、簡介

二、屬性列表

1、OptionsSelection:

  EnableAppearanceForcusedCell:選中的Cell的Appearance設定是否可用。預設為True;

  EnableAppearanceForcusedRow:選中的Node的Appearance設定是否可用。預設為True

  InvertSelection:設定選中風格是隻應用於選中的Cell,還是應用於除選中的Cell之外的所有Cell。預設為False,即後者; 

  MultiSelect:是否可以選擇多個Node。預設為False。

2、OptionsView:

   AutoCalcPreviewLineCount:是否自動計算預覽節段的高度。預設為True;

   AutoWidth:是否允許列自動調整寬度;預設為True;

   EnableAppearanceEvenRow:生成偶數Node時,是採用由

  TreeListAppearanceCollection.EvenRow屬性提供的Appearance

    設定,還是採用由TreeListAppearanceCollection.Row提供的

   Appearance設定。預設為False,即後者;

   EnableAppearanceOddRow:生成奇數Node時,是採用由

  TreeListAppearanceCollection.OddRow屬性提供的Appearance

    設定,還是採用由TreeListAppearanceCollection.Row提供的

   Appearance設定。預設為False,即後者;

   ShowButtons:是否顯示展開與收縮按鈕。預設為True;

   ShowCloumns:是否顯示列標題。預設為True;

   ShowFocusedFrame:在獲得焦點的Cell上,是否顯示焦點框架。預設為True;

   ShowHorzLines:是否顯示水平線。預設為True;

   ShowIndentAsRowStyle:是否用相應Node的Appearance設定來生成Tree的縮排。預設為False

   ShowIndicator:是否顯示Node的指示符面板。預設為True;

  ShowPreview:是否顯示預覽節段。預設為False;

  ShowRoot:是否在根Node間顯示連線線。預設為True;

   ShowRowFooterSummary:是否顯示分組腳註。預設為False;

  ShowSummaryFooter:是否顯示摘要腳註。預設為False;

  ShowVertLines:是否顯示垂直線。預設為True;

3、SelectImageList:選中Node時,顯示圖片的列表;

4、StateImageList:指明Node狀態的圖片的列表;

三、事件

四、使用

1、 如何隱藏TreeList的列頭

   設定TreeListr的OptionsView的ShowColumns屬性為:False

2、 如何預設展開所有的節點ExpandAll()

   tlvWells.ExpandAll();

    以及TreeNode.Expand   =   false   

    或者你可以控制展開的層數 reeView1.ExpandLevel=10; 展開10層

  this.treeList.Nodes[0].ExpandAll();// 第一層下的所有接點展開

3、 如何讓TreeList的每個結點高亮顯示?

程式碼如下:

private void treeList1_CustomDrawNodeCell(object sender, DevExpress.XtraTreeList.CustomDrawNodeCellEventArgs e)

    {

      TreeList node = sender as TreeList;

      if (e.Node == node.FocusedNode)

      {

        e.Graphics.FillRectangle(SystemBrushes.Window, e.Bounds);

        Rectangle r = new Rectangle(e.EditViewInfo.ContentRect.Left, e.EditViewInfo.ContentRect.Top,

        Convert.ToInt32(e.Graphics.MeasureString(e.CellText,  treeList1.Font).Width + 1), Convert.ToInt32(e.Graphics.MeasureString(e.CellText,treeList1.Font).Height));

        e.Graphics.FillRectangle(SystemBrushes.Highlight, r);

        e.Graphics.DrawString(e.CellText, treeList1.Font, SystemBrushes.HighlightText, r);

        e.Handled = true;

      }

    }

4、 資料繫結最基本的兩個屬性:KeyFieldName和ParentFieldName。

(這兩個屬性一設定就基本上可以實現分級了)可以通過程式碼的編寫實現,也可以直接在屬性裡面直接實現。這種資料庫設計是比較常見的,一般資料滿足樹形關係就可以這樣設計。繫結資料時,只需指定DataSource為對應 的DataTable,指定KeyFieldName為表主鍵欄位,ParentFieldName為表指向主鍵的外來鍵欄位名。

private void BindData()

     {

     this.tlOffice.DataSource = dtOffice;

     tlOffice.KeyFieldName = "OfficeID";

     //tlOffice.DataMember = "OfficeName";

     tlOffice.Columns["OfficeName"].Caption = "局名稱";

     tlOffice.ParentFieldName = "ParentOfficeID";

   }

5、 選擇某一節點時,該節點的子節點全部選擇  取消某一節點時,該節點的子節點全部取消選擇

      哪個節點引起行為的?節點是選中還是取消選中?由此確定方法的兩個引數:TreeListNode和CheckState。遍歷該節點及其子孫,並將其選中狀態設定為該節點的狀態即可。

/// 選擇某一節點時,該節點的子節點全部選擇 取消某一節點時,該節點的子節點全部取消選擇

  /// <param name="node"></param>

  /// <param name="state"></param>

  private void SetCheckedChildNodes(TreeListNode node, CheckState check)

  {

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

    {

      node.Nodes[i].CheckState = check;

      SetCheckedChildNodes(node.Nodes[i], check);

    }

}

上兩步寫好了,別忘了上面的兩個方法在TreeList_AfterCheckNode裡面觸發:

private void tlOffice_AfterCheckNode(object sender, DevExpress.XtraTreeList.NodeEventArgs e)

{

  SetCheckedChildNodes(e.Node, e.Node.CheckState);

  SetCheckedParentNodes(e.Node, e.Node.CheckState);

}

6、 某節點的子節點全部選擇時,該節點選擇;某節點的子節點未全部選擇時,該節點不選擇     

/// 某節點的子節點全部選擇時,該節點選擇  某節點的子節點未全部選擇時,該節點不選擇

   /// <param name="node"></param>

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

   private void SetCheckedParentNodes(TreeListNode node, CheckState check)

   {

     if (node.ParentNode != null)

     {

       CheckState parentCheckState = node.ParentNode.CheckState;

       CheckState nodeCheckState;

       for (int i = 0; i < node.ParentNode.Nodes.Count; i++)

       {

         nodeCheckState = (CheckState)node.ParentNode.Nodes[i].CheckState;

         if (!check.Equals(nodeCheckState))//只要任意一個與其選中狀態不一樣即父節點狀態不全選

         {

           parentCheckState = CheckState.Unchecked;

           break;

         }

         parentCheckState = check;//否則(該節點的兄弟節點選中狀態都相同),則父節點選中狀態為該節點的選中狀態

       }

       node.ParentNode.CheckState = parentCheckState;

       SetCheckedParentNodes(node.ParentNode, check);//遍歷上級節點

     }

   }

 上兩步寫好了,別忘了上面的兩個方法在TreeList_AfterCheckNode裡面觸發:

private void tlOffice_AfterCheckNode(object sender, DevExpress.XtraTreeList.NodeEventArgs e)

    {

      SetCheckedChildNodes(e.Node, e.Node.CheckState);

      SetCheckedParentNodes(e.Node, e.Node.CheckState);

    }

7、 獲取選中的複選框資料列表

?a

private List<int> lstCheckedOfficeID = new List<int>();//選擇局ID集合

   /// 獲取選擇狀態的資料主鍵ID集合

   /// <param name="parentNode">父級節點</param>

   private void GetCheckedOfficeID(TreeListNode parentNode)

   {

     if (parentNode.Nodes.Count == 0)

     {

       return;//遞迴終止

     }

     foreach (TreeListNode node in parentNode.Nodes)

     {

       if (node.CheckState == CheckState.Checked)

       {

         DataRowView drv = tlOffice.GetDataRecordByNode(node) as DataRowView;//關鍵程式碼,就是不知道是這樣獲取資料而糾結了很久(鬼知道可以轉換為DataRowView啊)

         if (drv != null)

         {

           int OfficeID = (int)drv["OfficeID"];

           lstCheckedOfficeID.Add(OfficeID);

         }

       }

       GetCheckedOfficeID(node);

     }

   }

  下面測試獲取主鍵列表:

private void btnCheck_Click(object sender, EventArgs e)

   {

     this.lstCheckedOfficeID.Clear();

     if (tlOffice.Nodes.Count > 0)

     {

       foreach (TreeListNode root in tlOffice.Nodes)

       {

         GetCheckedOfficeID(root);

       }

     }

     string idStr = string.Empty;

     foreach (int id in lstCheckedOfficeID)

     {

       idStr += id + " ";

     }

     MessageBox.Show(idStr);

   }

五、注意事項

1、從資料庫中讀取資料

方法一:直接點選控制元件

 這種方法連線後系統會自動生成一行程式碼:

?

1

this. 資料庫表名TableAdapter.Fill(this.dataDataSet4.資料庫表名);

 這種方法生成後不會像寫程式碼那樣連線後就會把第一行預設為根節點。而且一旦你要把可執行檔案拿走就不可用了。因為你在選擇資料庫的時候選的是絕對路徑。所以最好用下面的方法。

方法二:

用程式碼連線資料庫(寫的程式碼方法很多)       

?

1

2

String connectionString = "Provider=Microsoft.Jet.OleDb.4.0;Data Source=";

connectionString += @"D:\Data.mdb";//這用的是絕對路徑

應該用相對路徑。

(String connectionString = @"Provider=Microsoft.Jet.OleDb.4.0;Data Source=";

      connectionString += Application.StartupPath + @"\Data.mdb";

 )

      System.Data.OleDb.OleDbConnection con = new System.Data.OleDb.OleDbConnection(connectionString);

      con.Open();

      System.Data.OleDb.OleDbCommand cmd = new System.Data.OleDb.OleDbCommand("SELECT * FROM FS_STAFF", con);

      System.Data.OleDb.OleDbDataReader reader = cmd.ExecuteReader();

      DataTable table = new DataTable();

      table.Load(reader);

      gridControl2.DataSource = table;