对于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>