Hierarchical DesktopListBox with checkbox

Hello,
When I check the “parent” item (level 0), how do I check all its childs items (level 1)?
I tried this (without success, it ticks all the checkboxes):

For i As Integer = row + 1 To Me.RowCount - 1
   Me.CellCheckBoxStateAt(i, 0) = Me.CellCheckBoxStateAt(row, column)
  Next

Thanks

You need to check the indent level (RowDepthAt) of the rows below (stopping when you find one at the same indentation),
and also test whether the starting row is actually expanded.(RowExpandedAt)

So something like:

if me.rowexpandedat(row) then
//this row is expanded
for x as integer = row+1 to Me.RowCount - 1
if me.rowdepthat(x) > me.rowdepthat(row) then  //deeper than me
   me.CellCheckBoxStateAt(x,0) = me.CellCheckBoxStateAt(row,0)  
else
   //found one the same or less deep , so stop here
  exit for
end if
next
end if
1 Like

I used:
Sub CellAction(row As Integer, column As Integer) Handles CellAction
System.DebugLog “Cell Action”

Dim i As Integer

For i = 0 To 10
'LB.AddRow "Sub-Entrée " + Str(i)
LB.CellCheckBoxValueAt(i, 0) = Not LB.CellCheckBoxValueAt(i, 0)
Next
End Sub

and it Check or Uncheck the Rows:

rough…

Work fine ! Thanks you very much.

Hi @Jeff_Tullin
Is there a command to test if at least one Checkbox is checked without looping (for i=0 to RowCount …)?
Somewhat the equivalent of SelectedRowIndex?
DD

https://documentation.xojo.com/api/user_interface/desktop/desktoplistbox.html#desktoplistbox

Have nearly everything (hodw doy you set a column text to Bold ?)

look:
RowExpandedAt(RowNumber As Integer) As Boolean

Hello,
I realize that it works when you click and the row is already expanded. But if the row is checked when it is not expanded, its children remain unchecked. How to resolve this?
I tried to remove the condition “if Me.RowExpandedAt(row) then”, it doesn’t seem to be enough.

Finally, if I uncheck a “child” checkbox, then I want to put the parent in indeterminate state.
I tried this:

if Me.RowExpandedAt(row) then
  for x as integer = row-1 to 0
    if Me.RowDepthAt(x) < Me.RowDepthAt(row) then  //if less deep = my parent !
      Me.CellCheckBoxStateAt(x,0) = DesktopCheckbox.VisualStates.Indeterminate
    else
      //stop here !
      exit for
    end if
  next
end if

Thanks a lot,

Until a row is expanded, the child rows do not actually exist.
They cant be checked or unchecked.

The normal way to do this is to maintain a linked list or a database.

eg

Name Code Parent
AAA A1 nil
BBB B1 A1
BBC B2 A1
CCC C1 B2

giving:
AAA
BBB
BBC
CCC

Armed with a list like this, instead of traversing the Listbox, you traverse the list or database, and set a property of the row.
Then, when you display it in the listbox, you just check or uncheck based on the property

Name Code Parent Checked
AAA A1 nil False
BBB B1 A1 False
BBC B2 A1 True
CCC C1 B2 True

if I uncheck a “child” checkbox, then I want to put the parent in indeterminate state.
I tried this:

Aha.
More scope creep. :slight_smile:

So now you need a tristate condition… true , false , or indeterminate
But the database/list still works for this.
Maintain the list, and redraw the list if need be after a change is made.

Name Code Parent Checked
AAA A1 nil False
BBB B1 A1 False
BBC B2 A1 Indeterminate
CCC C1 B2 False
CCD C2 B2 True

It seems too complicated for the amateur that I am. I was thinking that it must be possible that when expanding the child rows to test if the “parent” row is checked (or not). In this case check the child lines as soon as they are created and vice versa.

On the other hand, we must be able to go back one by one the child rows (loop) to the parent line (if level +1) to modify the state of the checkbox (Invalidate)?
What do you think ?

I was thinking that it must be possible that when expanding the child rows to test if the “parent” row is checked (or not). In this case check the child lines as soon as they are created and vice versa.

When expanding, of course you can do this.
But if a row is collapsed, the child rows do not exist.
So while collapsed, you can not enquire about the state of the children, to be able to show an indeterminate state for the parent row.

The only sure way is to have a structure/linked list/database holding the actual data, and use that to set the state of the listbox at any time.

My app can archive emails. The mailboxes for each email client/IMAP account can be selected in a hierarchical listbox:

The data is saved to a database where each mailbox has 2 states for selection and expansion:

Except for archiving itself this is the most complex part of the app.

1 Like