Menu

CheckBox cascading selection

2013-12-02
2013-12-02
  • David kroukamp

    David kroukamp - 2013-12-02

    Hi there

    I am busy trying to make a treeview with tristate checkboxes and cascading selection of these checkboxes.

    So I have read the topic before where you said to enable virtual mode which will call ValuePushed and ValueNeeded Methods... from there what do I do? My code is looking something like this:

        public void Initialize(DatabaseUserControl dbuc)
        {
            databaseUserControl = dbuc;
            tableColumnsDictionary = this.FillTableAndColumnsDictionary();
            var treeModel = tableColumnsDictionary.PopulateTreeView();
            this.treeViewAudits.Model = treeModel;
            nodeCheckBox1.VirtualMode = true;
            nodeCheckBox1.ValueNeeded += vNeeded;
            nodeCheckBox1.ValuePushed += vPushed;
            nodeCheckBox1.IsEditEnabledValueNeeded += IsEditEnabledValueNeeded;
            nodeCheckBox1.EditEnabled = true;
        }
    
         private static void IsEditEnabledValueNeeded(object sender, NodeControlValueEventArgs e)
        {
            if (e.Node.Children.Count != 0)//parents may be tristate
            {
                return;
            }
    
            //children may not be tristate (only parents i.e Nodes with other Nodes)
            e.Value = 0;
            var nodeCheckBox = (NodeCheckBox)sender;
            var checkedState = (CheckState)nodeCheckBox.GetValue(e.Node);
            nodeCheckBox.SetValue(e.Node, checkedState == CheckState.Checked ? CheckState.Unchecked : CheckState.Checked);
    
        }
        private void vPushed(object sender, NodeControlValueEventArgs e)
        {
    
            //var nodeCheckBox = (NodeCheckBox)sender;
           // var checkedState = (CheckState)nodeCheckBox.GetValue(e.Node);
           // checkedState=CheckState.Checked;//causes stackoverflow
            //e.Value = 1;
        }
    
        private void vNeeded(object sender, NodeControlValueEventArgs e)
        {
    
           // var nodeCheckBox = (NodeCheckBox)sender;
            //var checkedState = (CheckState)nodeCheckBox.GetValue(e.Node);
           // checkedState = CheckState.Unchecked;//causes stackoverflow
            // e.Value = 0;
        }
    

    I do not know what to do in those methods.. I have a Custome Node class which looks like:

    internal sealed class AuditObjectNode : Aga.Controls.Tree.Node
    {
    
        private readonly string objName;
    
        public string ObjName
        {
            get
            {
                return this.objName;
            }
        }
    
        public CheckState Insert { get; set; }
    
        public CheckState Update { get; set; }
    
        public CheckState Delete { get; set; }
    
        public AuditObjectNode(string objName, CheckState insert, CheckState update, CheckState delete)
        {
            this.objName = objName;
            this.Insert = insert;
            this.Update = update;
            this.Delete = delete;
            this.Text = objName;
        }
    
    }
    

    Please can you advise on how to make checkbox cascading selection for tristate checkboxes. with children etc.

    Also the minute I enable virtual mode I am unable to edit the checkboxes states via a click... And yes EditEnabled is set to true, but im guesing its those ValuePushed and ValueNeeded methods causing the problem

     

    Last edit: David kroukamp 2013-12-02
  • David kroukamp

    David kroukamp - 2013-12-02

    Got a work around (without using VirtualMode). Simply set EditEnabled to true for all tristate NodeCheckBoxes (disable VirtualMode) than add method to be called for each NodeCheckBox :

        public void Initialize(DatabaseUserControl dbuc)
        {
            databaseUserControl = dbuc;
            tableColumnsDictionary = this.FillTableAndColumnsDictionary();
            var treeModel = tableColumnsDictionary.PopulateTreeView();
            this.treeViewAudits.Model = treeModel;
    
            nodeCheckBox1.IsEditEnabledValueNeeded += IsEditEnabledValueNeeded;
            nodeCheckBox2.IsEditEnabledValueNeeded += IsEditEnabledValueNeeded;
            nodeCheckBox3.IsEditEnabledValueNeeded += IsEditEnabledValueNeeded;
        }
    

    The method would look something like this:

        private static void IsEditEnabledValueNeeded(object sender, NodeControlValueEventArgs e)
        {
            var nodeCheckBox = (NodeCheckBox)sender;
            var node = e.Node;
            var checkedState = (CheckState)nodeCheckBox.GetValue(node);
            var parentNode = node.Parent;
    
            if (node.Children.Count != 0) //parents may be tristate
            {
                foreach (var n in node.Children)
                {
                    switch (checkedState)
                    {
                        case CheckState.Unchecked:
                            nodeCheckBox.SetValue(n, CheckState.Checked);
                            break;
                        case CheckState.Checked:
                            nodeCheckBox.SetValue(n, CheckState.Unchecked);
                            break;
                        case CheckState.Indeterminate:
                            nodeCheckBox.SetValue(n, CheckState.Checked);
                            break;
                    }
                }
            }
    
            //children may not be tristate (only parents i.e Nodes with other Nodes)
            e.Value = 0;
            var childNodeCheckState = checkedState == CheckState.Checked ? CheckState.Unchecked : CheckState.Checked;
            nodeCheckBox.SetValue(e.Node, childNodeCheckState);
    
            //there was not parent node so return
            if (parentNode == null)
            {
                return;
            }
    
            //a parent node exists check children and set parent tristate correctly
            var count = parentNode.Children.Count;
            var actualCount =
                parentNode.Children.Select(childNode => (CheckState)nodeCheckBox.GetValue(childNode)).
                           Count(childState => childState == CheckState.Checked);
    
            if (actualCount == 0)
                nodeCheckBox.SetValue(parentNode, CheckState.Unchecked);
            else if (count != actualCount)
                nodeCheckBox.SetValue(parentNode, CheckState.Indeterminate);
            else
                nodeCheckBox.SetValue(parentNode, CheckState.Checked);
        }
    
     

    Last edit: David kroukamp 2013-12-02

Log in to post a comment.