使用DEV控件也有一段時間了,一直想寫點東西。最近又使用到TreeList控件,這個控件對於剛使用的人來說確實不好掌握。我想把自己知道的寫下來,讓還不熟悉的慢慢學會使用,對於會使用的大家交流下。如果有用的不正確或不恰當的歡迎各位指正批評。
一,第一步從控件庫里拖出TreeList
二,設置屬性
this.treeList1.OptionsView.ShowCheckBoxes = true;
this.treeList1.OptionsView.ShowColumns = false;
this.treeList1.OptionsView.ShowHorzLines = false;
this.treeList1.OptionsView.ShowIndicator = false;
this.treeList1.OptionsView.ShowVertLines = false;
三,構造測試數據(參考方法 FrmTreeList_Load)
四,設置選中項(參考方法 SetCheckState )
五,當前操作的節點為某個節點的最后一個子節點時,設置父節點的狀態
這里需要一個 事件即:treeList1_AfterCheckNode 這個方法在屬性事件里找到。
頁面所有代碼如下:

1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Threading.Tasks; 9 using System.Windows.Forms; 10 using DevExpress.XtraTreeList.Nodes; 11 12 namespace WinForm2 13 { 14 public partial class FrmTreeList : DevExpress.XtraEditors.XtraForm 15 { 16 public FrmTreeList() 17 { 18 InitializeComponent(); 19 } 20 21 private DataTable dt = new DataTable(); 22 /// <summary> 23 /// 要被選中的節點 24 /// </summary> 25 public List<string> SelectItem = new List<string>(); 26 27 //初始化方法加載測試數據 28 private void FrmTreeList_Load(object sender, EventArgs e) 29 { 30 dt.Columns.Add("ID", typeof(int)); 31 dt.Columns.Add("ItemName", typeof(string)); 32 dt.Columns.Add("ParentID", typeof(int)); 33 34 DataRow dr = dt.NewRow(); 35 dr["ID"] = 1; 36 dr["ItemName"] = "根節點"; 37 dr["ParentID"] = -1; 38 dt.Rows.Add(dr); 39 40 DataRow dr2 = dt.NewRow(); 41 dr2["Id"] = 2; 42 dr2["ItemName"] = "根節點2"; 43 dr2["ParentID"] = 0; 44 dt.Rows.Add(dr2); 45 46 DataRow dr3 = dt.NewRow(); 47 dr3["ID"] = 3; 48 dr3["ItemName"] = "根節點3"; 49 dr3["ParentID"] = 0; 50 dt.Rows.Add(dr3); 51 52 DataRow dr4 = dt.NewRow(); 53 dr4["ID"] = 4; 54 dr4["ItemName"] = "子節點1"; 55 dr4["ParentID"] = 1; 56 dt.Rows.Add(dr4); 57 58 DataRow dr5 = dt.NewRow(); 59 dr5["ID"] = 5; 60 dr5["ItemName"] = "子節點2"; 61 dr5["ParentID"] = 1; 62 dt.Rows.Add(dr5); 63 64 DataRow dr6 = dt.NewRow(); 65 dr6["ID"] = 6; 66 dr6["ItemName"] = "子子節點1"; 67 dr6["ParentID"] = 5; 68 dt.Rows.Add(dr6); 69 70 DataRow dr7 = dt.NewRow(); 71 dr7["ID"] = 7; 72 dr7["ItemName"] = "子子節點2"; 73 dr7["ParentID"] = 5; 74 dt.Rows.Add(dr7); 75 76 this.treeList1.DataSource = dt; 77 this.treeList1.KeyFieldName = "ID"; 78 this.treeList1.ParentFieldName = "ParentID"; 79 80 //這里是用來測試的節點 81 SelectItem.Add("子子節點1"); 82 SelectItem.Add("根節點2"); 83 // 設置初始狀態 84 SetCheckState(SelectItem, "ItemName"); 85 86 } 87 88 #region 按配置選中相關節點項 89 90 //設置節點的選中狀態 91 private void SetCheckState(List<string> list, string fieldName) 92 { 93 foreach (TreeListNode n in treeList1.Nodes) 94 { 95 DataRowView drv = (DataRowView)treeList1.GetDataRecordByNode(n); 96 string nodeName = (drv != null && drv[fieldName] != null) ? Convert.ToString(drv[fieldName]) : string.Empty; 97 if (list.Contains(nodeName)) 98 { 99 n.CheckState = CheckState.Checked; 100 } 101 //如果當前結點有子結點,再枚舉所有子結點 102 if (n.HasChildren) 103 this.SelectedChildNode(n, fieldName); 104 } 105 106 } 107 108 /// <summary> 109 /// 設置子節點狀態 110 /// </summary> 111 /// <param name="parentNode"></param> 112 private void SelectedChildNode(TreeListNode parentNode, string fieldName) 113 { 114 foreach (TreeListNode n in parentNode.Nodes) 115 { 116 DataRowView drv = (DataRowView)treeList1.GetDataRecordByNode(n); 117 string nodeName = (drv != null && drv[fieldName] != null) ? Convert.ToString(drv[fieldName]) : string.Empty; 118 if (SelectItem.Contains(nodeName)) 119 { 120 n.CheckState = CheckState.Checked; 121 // 這里是將父節點,父節點的父節點設置為選中狀態 122 SelectedParentNode(n); 123 } 124 if (n.HasChildren) this.SelectedChildNode(n, fieldName); 125 } 126 } 127 128 /// <summary> 129 /// 設置相關的父節點被選中 130 /// </summary> 131 /// <param name="parentNode"></param> 132 private void SelectedParentNode(TreeListNode parentNode) 133 { 134 if (parentNode.ParentNode != null) 135 { 136 parentNode.ParentNode.CheckState = CheckState.Checked; 137 SelectedParentNode(parentNode.ParentNode); 138 } 139 } 140 141 #endregion 142 143 #region 節點選中或取消相關處理 144 145 //節點選中后處理 146 private void treeList1_AfterCheckNode(object sender, DevExpress.XtraTreeList.NodeEventArgs e) 147 { 148 SetChildNodeState(e.Node, e.Node.CheckState); 149 SetParentNodeState(e.Node); 150 } 151 152 //設置子節點的狀態(當選中父節點時所有的子節點也要選中) 153 private void SetChildNodeState(TreeListNode node, CheckState state) 154 { 155 if (node.HasChildren) 156 { 157 foreach (TreeListNode item in node.Nodes) 158 { 159 item.CheckState = state; 160 if (item.HasChildren) SetChildNodeState(item, state); 161 } 162 } 163 } 164 165 //檢查節點是否是最后一個被選中或取消的子節點,如果是要對父節點進行設置(選中或不選中) 166 private void SetParentNodeState(TreeListNode node) 167 { 168 if (node.ParentNode != null) 169 { 170 // 方法一 171 //bool state = false; 172 //foreach (TreeListNode item in node.ParentNode.Nodes) 173 //{ 174 // state = item.Checked; 175 // if (state) break; 176 //} 177 //node.ParentNode.Checked = state; 178 179 // 方法二 180 bool state = true; 181 node.ParentNode.CheckState = CheckState.Checked; 182 foreach (TreeListNode item in node.ParentNode.Nodes) 183 { 184 if (item.CheckState != node.CheckState) 185 { 186 state = false; 187 break; 188 } 189 } 190 if (state) node.ParentNode.CheckState = node.CheckState; 191 192 // 遞歸檢查父父節點 193 SetParentNodeState(node.ParentNode); 194 } 195 } 196 197 #endregion 198 199 // 設置選中項的背景 200 private void treeList1_CustomDrawNodeCell(object sender, DevExpress.XtraTreeList.CustomDrawNodeCellEventArgs e) 201 { 202 if (e.Node.Checked) 203 { 204 e.Appearance.BackColor = Color.LightBlue; 205 } 206 else 207 { 208 e.Appearance.BackColor = Color.Transparent; 209 } 210 } 211 } 212 }