简体   繁体   中英

TreeView with CheckBoxes in c#

I have a tree view with checkboxes in c#, I want that when the user checks one node all the nodes that there are on the levels below automatic checked also. Does anyone know about way to do that without run with recorsive fnction on all the tree each time that the user checks some node?

Thanks

//this function returns the treeView.

   public TreeView GetTreeView()
    {

        getSubject();
        // fill the treeview with all subjects.
        foreach (Subject subject in subjects)
        {
            //for each root subject fill all the his children.
            if (subject.subjestId == subject.parentSubject)
            {
                TreeNode node = new TreeNode(subject.subjectString, subject.subjestId, subject.subjestId);
                addChild(node, subject.subjestId);
                tv.Nodes.Add(node);
            }
        }
        return tv;
    }
   // for each subject return sub subjects.
   private void addChild(TreeNode node, int parentId)
    {
        foreach (Subject subject in subjects)
        {
            if (subject.parentSubject == parentId && subject.parentSubject != subject.subjestId)
            {
                TreeNode childNode = new TreeNode(subject.subjectString, subject.subjestId, subject.subjestId);
                addChild(childNode, subject.subjestId);
                node.Nodes.Add(childNode);
            }
        }
    }

Recursion. Like this:

    bool busy = false;

    private void treeView1_AfterCheck(object sender, TreeViewEventArgs e) {
        if (busy) return;
        busy = true;
        try {
            checkNodes(e.Node, e.Node.Checked);
        }
        finally {
            busy = false;
        }
    }

    private void checkNodes(TreeNode node, bool check) {
        foreach (TreeNode child in node.Nodes) {
            child.Checked = check;
            checkNodes(child, check);
        }
private void treeView1_AfterCheck(object sender, TreeViewEventArgs e) {
  foreach (TreeNode child in e.Node.Nodes) {
    child.Checked = e.Node.Checked;
  }
}

This is a better solution

private void trvMenuList_AfterCheck(object sender, TreeViewEventArgs e)
        {
            SetChildrenChecked(e.Node, e.Node.Checked);

        }

  private void SetChildrenChecked(TreeNode treeNode, bool checkedState)
        {
            foreach (TreeNode item in treeNode.Nodes)
            {
                if (item.Checked != checkedState)
                {
                    item.Checked = checkedState;
                }
                SetChildrenChecked(item, item.Checked);
            }
        }

As a number of the answers state, create a recursive 'set checked to children' function, then call it AfterCheck on the tree.

The framework unfortunately gives you a call back to AfterCheck even if you set the check value in code, and although this may not be noticeable in small trees adds a massive amount of exponential extra work for your app to do. To avoid it, filter AfterCheck to only fire your new function if it has been triggered by user.

    private void tree_AfterCheck(object sender, TreeViewEventArgs e)
    {
        if (e.Action != TreeViewAction.Unknown)
        {
            SetChildrenChecked(e.Node);
        }
    }

    private void SetChildrenChecked(TreeNode treeNode)
    {
        foreach (TreeNode item in treeNode.Nodes)
        {
            if (item.Checked != treeNode.Checked)
            {
                item.Checked = treeNode.Checked;
            }

            if (item.Nodes.Count > 0)
            {
                SetChildrenChecked(item);
            }                
        }
    }

如果你想在WinForms中这样做,那么我认为你必须通过递归手动完成 - 我不知道更好的方法。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM