本文记录一段很简单的代码,如下图,左边的UltraTree控件,Check/Unckeck父节点时Check/Unckeck其子节点(递归),Check子节点时Check其父节点(递归),当父节点下的所有子节点都Unckeck时,Uncheck父节点。Check的节点记录在右边的UltraTree控件。没多大意思,写代码时刚好碰到了,就记下来了。
先往Form上放两个UltraTree,左边的命名为treeCategories,右边的命名为treeSelectedCategories,为treeCategories添加事件AfterCheck。接下来贴代码:
protected void CheckParent(UltraTreeNode node)
{
// Check任意一个子节点,则Check父节点
if (node.Parent != null)
{
if (node.CheckedState == CheckState.Checked)
{
node.Parent.CheckedState = CheckState.Checked;
}
else if (node.CheckedState == CheckState.Unchecked)
{
bool checkParentNode = false;
foreach (UltraTreeNode siblingNode in node.Parent.Nodes)
{
if (siblingNode.CheckedState == CheckState.Checked)
{
checkParentNode = true;
break;
}
}
![](/Images/OutliningIndicators/InBlock.gif)
if (checkParentNode)
{
node.Parent.CheckedState = CheckState.Checked;
}
else
{
node.Parent.CheckedState = CheckState.Unchecked;
}
}
![](/Images/OutliningIndicators/InBlock.gif)
CheckParent(node.Parent);
}
}
protected void CheckChild(UltraTreeNode node)
{
// Check父节点,则Check所有子节点
if (node.Nodes.Count > 0)
{
foreach (UltraTreeNode childNode in node.Nodes)
{
childNode.CheckedState = node.CheckedState;
CheckChild(childNode);
}
}
else
{
OnLeafNodeCheck(node); // 跳出递归直到叶子节点
}
}
protected void OnLeafNodeCheck(UltraTreeNode node)
{
// 叶子节点添加到右边的UltraWinTree
if (node.CheckedState == CheckState.Checked)
{
treeSelectedCatagories.Nodes.Add(node.Text);
}
else if (node.CheckedState == CheckState.Unchecked)
{
foreach (UltraTreeNode selectedNode in treeSelectedCatagories.Nodes)
{
if (node.Text.CompareTo(selectedNode.Text) == 0)
{
treeSelectedCatagories.Nodes.Remove(selectedNode);
}
}
}
}
private void treeCatagories_AfterCheck(object sender, Infragistics.Win.UltraWinTree.NodeEventArgs e)
{
// 移除委托,防止递归函数再次触发事件
treeCatagories.AfterCheck -= treeCatagories_AfterCheck;
![](/Images/OutliningIndicators/InBlock.gif)
CheckChild(e.TreeNode);
CheckParent(e.TreeNode);
![](/Images/OutliningIndicators/InBlock.gif)
// 重新指定委托,使下次事件时递归函数能被调用一次
treeCatagories.AfterCheck += treeCatagories_AfterCheck;
}
先往Form上放两个UltraTree,左边的命名为treeCategories,右边的命名为treeSelectedCategories,为treeCategories添加事件AfterCheck。接下来贴代码:
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
CheckChild和CheckParent是两个递归函数,分别向下和向上搜索节点,其中CheckChild函数在递归到叶子节点时又调用OnLeafNodeCheck函数记录Check的叶子节点并跳出递归。代码看一遍就明白了,总觉得我这递归好像写的比较笨,要是哪位朋友看后能不吝赐教我会很感谢。
另外这里要特别注意由于是往UltraTree中添加节点,递归的过程中会再次触发AfterCheck事件造成死循环,因此我的办法是在调用两个递归函数前后动态移除/增加委托,不知道这样是否对性能有很大的损耗。