Search code examples
c#recursionobjectlistviewtreelistview

ObjectListView - TreeListView Auto TriStateChecking


Is there anyone out there that has successfully gotten tri-state checkboxes working correctly in a TreeListView, without using a property in the model object to store the checkstate?

So, for example, a node is checked. All of its children (and childrens children etc) should be checked and then all its parents/grandparents should be checked according to its siblings CheckStates.

I have tried a couple of methods, but each way I get an ArgumentOutOfRange/ArgumentException within the TreeListView class. This includes the following:

  • Storing all the nodes CheckStates in a Dictionary and using as a lookup with CheckStateGetter event
  • Recursively calling a function when an items CheckState changes (and ensuring the subsequent ItemCheck events are ignored while programatically changing CheckStates)
  • Calling a function to determine immediate children/parent states and letting the TreeListView fire the ItemChecked event for each of the affected nodes.

I constantly get errors from the following functions (in TreeListView.cs):

  • GetNthItem()
  • GetChildren() - and then expanding/collapsing the shild in the GUI
  • ProcessLButtonDown()

If anyone out there has been successful with this I am all ears.


Solution

  • I had some problems with the TreeListView as well and found a problem in the GetChildren() functions.

    GetChildren was unnecessarily trying to expand the related branch to fetch the children. This caused the internal state to be shown as expanded while the view stayed collapsed and caused problems with internal indexing.

    Original method:

        public virtual IEnumerable GetChildren(Object model) {
            Branch br = this.TreeModel.GetBranch(model);
            if (br == null || !br.CanExpand)
                return new ArrayList();
    
            if (!br.IsExpanded)  // THIS IS THE PROBLEM
                br.Expand();
    
            return br.Children;
        }
    

    Fixed method:

        public virtual IEnumerable GetChildren(Object model) {
            Branch br = this.TreeModel.GetBranch(model);
            if (br == null || !br.CanExpand)
                return new ArrayList();
    
            br.FetchChildren();
    
            return br.Children;
        }
    

    Maybe this solves at least some of your problems.