heminzhou

程序员民工的笔记本

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
      本文记录一段很简单的代码,如下图,左边的UltraTree控件,Check/Unckeck父节点时Check/Unckeck其子节点(递归),Check子节点时Check其父节点(递归),当父节点下的所有子节点都Unckeck时,Uncheck父节点。Check的节点记录在右边的UltraTree控件。没多大意思,写代码时刚好碰到了,就记下来了。



      先往Form上放两个UltraTree,左边的命名为treeCategories右边的命名为treeSelectedCategoriestreeCategories添加事件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;
                        }

                    }


                    
if (checkParentNode)
                    
{
                        node.Parent.CheckedState 
= CheckState.Checked;
                    }

                    
else
                    
{
                        node.Parent.CheckedState 
= CheckState.Unchecked;
                    }

                }


                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;

            CheckChild(e.TreeNode);
            CheckParent(e.TreeNode);

            
// 重新指定委托,使下次事件时递归函数能被调用一次
            treeCatagories.AfterCheck += treeCatagories_AfterCheck;
        }

      CheckChild和CheckParent是两个递归函数,分别向下和向上搜索节点,其中CheckChild函数在递归到叶子节点时又调用OnLeafNodeCheck函数记录Check的叶子节点并跳出递归。代码看一遍就明白了,总觉得我这递归好像写的比较笨,要是哪位朋友看后能不吝赐教我会很感谢。

      另外这里要特别注意由于是往UltraTree中添加节点,递归的过程中会再次触发AfterCheck事件造成死循环,因此我的办法是在调用两个递归函数前后动态移除/增加委托,不知道这样是否对性能有很大的损耗。

posted on 2007-08-20 16:22  heminzhou  阅读(1463)  评论(1编辑  收藏  举报