對於TreePanel的Node我們需求是:1.選中某個節點A的CheckBox,節點A的所有子節點全部選中;2.節點A的所有子節點如果都選中,則A節點選中;3.節點A的某些節點選中,某些節點不選中,則A節點處於半選狀態。如下圖所示:
如何來實現呢?
研究發現TreePanel的節點的Checkbox可發現通過node.getUI().checkbox可以獲取到checkbox。設置checkbox的checked屬性為true / false 可以設置checkbox選中或者非選擇,那么三態的半選中狀態如何設置呢?可以通過設置checkbox的indeterminate屬性為true,checked為false可以實現。因此,可以如下處理:

1 <ext:TreePanel runat="server" ID="tree" RootVisible="false"> 2 <Loader> 3 <ext:TreeLoader DataUrl="/Home/GetNode"> 4 <BaseParams> 5 <ext:Parameter Name="pNodeId" Value="node.id" Mode="Raw"> 6 </ext:Parameter> 7 </BaseParams> 8 </ext:TreeLoader> 9 </Loader> 10 <Root> 11 <ext:AsyncTreeNode NodeID="root" Expanded="true"> 12 </ext:AsyncTreeNode> 13 </Root> 14 <Listeners> 15 <CheckChange Fn="NodeCheckChange" /> 16 <ExpandNode Fn="ExpandNode" /> 17 </Listeners> 18 </ext:TreePanel>

1 public ActionResult GetNode(string pNodeId) 2 { 3 if (pNodeId == "root") 4 { 5 pNodeId = ""; 6 } 7 TreeNodeCollection nodeList = new TreeNodeCollection(); 8 for (int i = 0; i < 5; i++) 9 { 10 AsyncTreeNode node = new AsyncTreeNode 11 { 12 NodeID = pNodeId + "." + (i + 1), 13 Checked = ThreeStateBool.False, 14 Text = string.Format("Node{0}", i + 1) 15 }; 16 nodeList.Add(node); 17 } 18 string json = nodeList.ToJson(); 19 return Content(json); 20 }

1 <script type="text/javascript"> 2 //設置節點子級全部選中 3 function SetChildNodeChecked(node) { 4 var isChecked = node.attributes.checked; 5 var childCount = node.childNodes.length; 6 if (childCount > 0) { 7 for (var i = 0; i < childCount; i++) { 8 var child = node.childNodes[i]; 9 var checkBox = child.getUI().checkbox; 10 child.attributes.checked = isChecked; 11 checkBox.checked = isChecked; 12 checkBox.indeterminate = false; 13 this.SetChildNodeChecked(child); 14 } 15 } 16 } 17 //設置節點父節點選中狀態 18 function SetParentNodeCheckState(node) { 19 var parentNode = node.parentNode; 20 if (parentNode != null) { 21 var checkBox = parentNode.getUI().checkbox; 22 var isAllChildChecked = true; 23 var someChecked = false; 24 var childCount = parentNode.childNodes.length; 25 for (var i = 0; i < childCount; i++) { 26 var child = parentNode.childNodes[i]; 27 if (child.attributes.checked) { 28 someChecked = true; 29 } 30 else if (child.getUI().checkbox.indeterminate == true && child.getUI().checkbox.checked == false) { 31 someChecked = true; 32 isAllChildChecked = false; 33 break; 34 } 35 else { 36 isAllChildChecked = false; 37 } 38 } 39 if (isAllChildChecked && someChecked) { 40 parentNode.attributes.checked = true; 41 if (checkBox != null) { 42 checkBox.indeterminate = false; 43 checkBox.checked = true; 44 } 45 } 46 else if (someChecked) { 47 parentNode.attributes.checked = false; 48 if (checkBox != null) { 49 checkBox.indeterminate = true; 50 checkBox.checked = false; 51 } 52 } 53 else { 54 parentNode.attributes.checked = false; 55 if (checkBox != null) { 56 checkBox.indeterminate = false; 57 checkBox.checked = false; 58 } 59 } 60 61 this.SetParentNodeCheckState(parentNode); 62 } 63 } 64 //選擇指標類型結點時的操作:取消當前選擇結點以外的其它結點的選中狀態 65 function NodeCheckChange(node) { 66 SetChildNodeChecked(node); 67 SetParentNodeCheckState(node); 68 } 69 70 function ExpandNode(node) { 71 SetChildNodeChecked(node); 72 } 73 </script>