Search code examples
c#recursionobjectlistviewtri-state-logic

Determine selected tristate


I have a treeview that displays a hierarchy of objects of type Company.

Company has (among others) a property Bool? Checked. I am using that value in the checkbox for each row. I would like the checkbox to (also) indicate if any childs has been selected, but Im not sure how to build the Getter for the Checked property.

I guess the problem is that the value does not only represent the current objects value, but also the combined value of the childs. Is it solvable or do I need to rethink?

Example of tristate tree

This is the outcome I would like to get:

  • Checked = True (if the item itself is checked)
  • Checked = False (if the item itself is not checked AND all childs/grandchilds are not checked)
  • Checked = Null (If the item itself is not checked and SOME childs/grandchilds are checked)
  • Checked = Null (if the item itself is not checked and ALL childs/grandchilds are checked)

Class Company:

public class Company
{
    public Company()
    {
        this.childs = new List<Company>();
    }
    public int ID { get; set; }
    public string Title { get; set; }
    public List<Company> childs { get; set; }
    public int NrOfChilds { get { return childs.Count; } }
    public bool Checked {
        get { ??? }
        set { this.Checked = value; }
    }

Solution

  • Ok, so using nullable bool is an OLV requirement right?

    But shouldn't something this work to achieve what you want?

    class Entity {
        private bool? _CheckState;
        public List<Entity> ChildEntities { get; set; }
    
        public Entity() {
            _CheckState = false;
            ChildEntities = new List<Entity>();
        }
    
        public bool? CheckState {
            get {
                if (_CheckState == true) {
                    return true;
                } else if (ChildEntities.All(child => child.CheckState == false)) {
                    return false;
                } else {
                    return null;
                }
            }
            set { _CheckState = value; }
        }
    }