【问题标题】:TreeView feature to uncheck all other nodesTreeView 功能取消选中所有其他节点
【发布时间】:2012-06-16 04:04:58
【问题描述】:

这是我要实现的功能:

  1. 正常点击鼠标查看树节点,用户可以多选。

  2. 当用户按住Ctrl+鼠标时,我希望鼠标点击的树节点被选中,所有其他节点都被取消选中。

我有一个版本,但它并不优雅:

有什么建议吗?

如果要测试代码,请将 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;
            }
        }
    }
}

【问题讨论】:

    标签: c# .net winforms treeview


    【解决方案1】:

    通过继承和递归使其优雅:

    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;
    }
    

    【讨论】:

    • Thx,有点不同的是,在“Ctrl”模式下,我的要求会使节点被选中,即使它是从选中到未选中。我只是添加了一个 e.Node.Checked = true;就在检查之前=假;再次感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多