TreeView功能取消选中所有其他节点

时间:2012-06-13 08:19:02

标签: c# .net winforms treeview

这是我想要实现的功能:

  1. 通过单击鼠标检查树节点,用户可以多次选择。

  2. 当用户按住Ctrl +鼠标时,我想要检查鼠标点击的树节点,并且取消选中所有其他节点。

  3. 我有一个版本但不优雅:

    有什么建议吗?

    如果要测试代码,请将TreeViewAdv和TreeNodeAdv替换为普通的TreeView和TreeNode。

    using Syncfusion.Windows.Forms.Tools;
    
    namespace treeviewtest
    {
        public partial class Form1 : Form
        {
            TreeNodeAdv CurrentNode = null;
            public Form1()
            {
                InitializeComponent();
            }
    
            private void treeViewAdv1_AfterCheck(object sender, Syncfusion.Windows.Forms.Tools.TreeNodeAdvEventArgs e)
            {
                TreeViewAdv tree = sender as TreeViewAdv;
                if (Control.ModifierKeys == Keys.Control 
                      && e.Action!= TreeViewAdvAction.Unknown)
                {
    
                    foreach (TreeNodeAdv node in tree.Nodes)
                    {
                        if (node.CheckState == CheckState.Checked && node != CurrentNode)
                            node.Checked = false;
    
                        foreach (TreeNodeAdv n in node.WalkTree())
                        {
                            if (n.CheckState == CheckState.Checked && n != CurrentNode)
                                n.Checked = false;
                        }
                    }
                }
                CurrentNode = null;
            }
    
            private void treeViewAdv1_BeforeCheck(object sender, TreeNodeAdvBeforeCheckEventArgs e)
            {
                if (Control.ModifierKeys == Keys.Control && CurrentNode == null)
                {
                    CurrentNode = e.Node;
                    if (e.NewCheckState == CheckState.Unchecked)
                    {
                        TreeViewAdv tree = sender as TreeViewAdv;
                        foreach (TreeNodeAdv node in tree.Nodes)
                        {
                            if (node.CheckState == CheckState.Checked && node != CurrentNode)
                                node.Checked = false;
    
                            foreach (TreeNodeAdv n in node.WalkTree())
                            {
                                if (n.CheckState == CheckState.Checked && n != CurrentNode)
                                    n.Checked = false;
                            }   
                        }
                        e.Cancel = true;
                    }
                }
            }
        }
    
        public static class externtree
        {
            public static IEnumerable<TreeNodeAdv> WalkTree(this TreeNodeAdv node)
            {
                if (node == null)
                    yield break;
    
                // return itself first
                yield return node;
    
                // return children
                if (node.HasChildren)
                {
                    foreach (TreeNodeAdv cNode in node.Nodes)
                        foreach (TreeNodeAdv iNode in cNode.WalkTree())
                            yield return iNode;
                }
            }
        }
    }
    

1 个答案:

答案 0 :(得分:2)

使用继承和递归使其更加优雅:

using System;
using System.Windows.Forms;

class MyTreeView : TreeView {
    protected override void OnAfterCheck(TreeViewEventArgs e) {
        if (checking) return;
        checking = true;
        if (e.Node.Checked && (Control.ModifierKeys & Keys.Control) == Keys.Control) {
            uncheckNodes(this.Nodes, e.Node);
        }
        checking = false;
        base.OnAfterCheck(e);
    }

    private void uncheckNodes(TreeNodeCollection nodes, TreeNode except) {
        foreach (TreeNode node in nodes) {
            if (node != except) node.Checked = false;
            uncheckNodes(node.Nodes, except);
        }
    }
    private bool checking;
}