• 使用泛型委托简化TreeView递归


    如以下代码所示,方法内有整型变量k,声明泛型委托hanlder并在内部对k进行自增操作,打印k得到101。

    static void Main(string[] args)
    {
        int k = 100;
        Action handler = () => k++;
        handler();
        Console.WriteLine(k);
    }

    WinForm中的TreeView常常要解决类似“父节点与子节点勾选”问题,注册TreeView.AfterCheck事件并添加递归方法很容易实现,现在添加需求,要求计算所有勾选状态TreeView的子节点;再添加需求,现在有第三方TreeView能实现类似Win7中“子节点非全选状态下父节点半选的状态”,现需要对半选节点计数……

    基本上需要为每个需求写上一个方法并添加out或ref修饰的计数参数或添加公共变量,代码不是那么好看了。现添加两个方法:

    private void treeNodeWalkSequence(TreeNode treeNode, Action<TreeNode> handler)
    {
        handler(treeNode);
        foreach (TreeNode node in treeNode.Nodes)
        {
            treeNodeWalkSequence(node, handler);
        }
    }
    private void treeNodeWalkReversed(TreeNode treeNode, Action<TreeNode> handler)
    {
        handler(treeNode);
        if (treeNode.Parent != null)
        {
            treeNodeWalkReversed(treeNode.Parent, handler);
        }            
    }

    treeNodeWalkSequence实现了子节点的前序遍历,treeNodeWalkReversed实现了父节点的回溯。

    对父子节点勾选的需求实现如下:

    private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
    {
        if (e.Action != TreeViewAction.Unknown)
        {
            Action<TreeNode> handler = treeNode => treeNode.Checked = e.Node.Checked;
            treeNodeWalkSequence(e.Node, handler);
    
            Action<TreeNode> handler2 = treeNode =>
            {
                if (treeNode.Parent != null)
                {
                    bool flag = true;
                    foreach (TreeNode sibling in treeNode.Parent.Nodes)
                    {
                        if (!sibling.Checked)
                        {
                            flag = false;
                            break;
                        }
                    }
                    treeNode.Parent.Checked = flag;
                }
            };
            treeNodeWalkReversed(e.Node, handler2);
        }
    }

    对勾选状态的节点计数实现如下:

    private void button1_Click(object sender, EventArgs e)
    {
        int n = 0;
        Action<TreeNode> handler = treeNode =>
        {
            if (treeNode.Checked)
            {
                n++;
            }
        };
        
        //or
        //Action<TreeNode> handler = treeNode => n += treeNode.Checked ? 1 : 0;
    
        foreach (TreeNode treeNode in treeView1.Nodes)
        {
            treeNodeWalkSequence(treeNode, handler);
        }
    
        label1.Text = String.Format("count: {0}", n);
    }

    没有公共变量,方法容易理解,逻辑简单容易维护。如有疏漏,请不吝指正。

  • 相关阅读:
    介绍一种很好用的任务调度平台
    java中的进制与操作符
    类再生(合成、继承、final)
    初始化
    重新学习Spring2——IOC和AOP原理彻底搞懂
    重新学习Spring一--Spring在web项目中的启动过程
    JDK并发包
    java并行程序基础
    MVC模式
    访问者模式
  • 原文地址:https://www.cnblogs.com/Jusfr/p/2555067.html
Copyright © 2020-2023  润新知