ListBox.RowIsFolder functionality in older versions

I am using an older version of RS, and I need to be able to tell if a row is hierarchical, as well as toggle that property. The later versions of XOJO has a ListBox.RowIsFolder property which appears to do what I want, but that is not available in the version I am using.

Is there an easy way to do this, or do I need to delete the row and reinsert as either a folder or row based on the current data being displayed, and then repopulate the cells/celltags?

You’ll have to do this :(. It’s ugly, but it works.

Thanks.

I’m adding ‘RowIsFolder’ methods which extend the listbox class to do this, and I can see how to code the part which changes from one mode to another, but I’m not sure how to tell if the exiting row is a hierarchical row or not. Is there a way I can do that?

The only way is for you to track it in a rowtag or something so when you add a folder you set some flag that say “this is a folder row” or not

Ok, thanks. Between keeping track of that setting, as well as knowing which hidden columns are used past the listbox’s visible count to store data, this is quickly getting much more complicated than I had originally hoped, so I may have to rethink using the global extension methods for now, and just code for the circumstance I have to deal with at this time . When I have more time, I’ll see if I can make it more globally usable.

Why don’t you define a class with the required properties and store that in the RowTag?

E.g.

Class RowInfo
Property IsFolder as Boolean
Property data as variant
Etc

That’s what I am planning. I am already storing something else in the row tag, but I am using a subclass for this listbox, so I will need to override the ‘row tag’ method for the subclass to store a variant array so that I can store both the info for that row, as well as what each instance sets as the row tag. I had been hoping to use extension methods so that it would work for all list boxes in the program automatically, but for now I will settle for using the subclass for this specific use.

The approach I used take is to define a Class that can hold the Rowtag as variant, the indentLevel and the Child Information. I overrode the RowTag method to return to just return/Create the rowtag and had methods to return IndentLevel and IsFolder…

Of course I also had to override the AddFolder method as well so that the relevant fields data got assigned when a Folder was added.

Yes it was pain to write, but once I had the subclass I did not have to worry about it again.

That said I should update my code to to use the new listbox methods. My code still works of course, but using the new functionality would simplify things.

  • Karen

This is what I have come up with so far, it seems to work well enough to change the row type, I will test it more thoroughly later (I haven’t actually tested it creating child rows just yet). I am using a variant array instead of a class just for simplicity (the listbox subclass is self contained, and not dependent on any external classes). I may change that in the future when I have more time to make it more robust, and control more of the hierarchical functions. My current need is just to show options for only one of the columns (the rest of the data will be the same across all child rows), and that is easily handled in a single celltag for now.

[code]Sub AddFolder(Text As String)
super.AddFolder(text)
call setRowData(me.LastIndex, true)
End Sub
Sub AddRow(Text As String)
super.AddRow(text)
call setRowData(me.LastIndex, False)
End Sub
Sub Cell(row As Integer, column As Integer, Assigns value As Variant)
super.Cell(row, column) = value
self.mMaxColumn = max (self.mMaxColumn, Column)
End Sub
Sub CellTag(row As Integer, column As Integer, Assigns value As Variant)
super.CellTag(row, column) = value
self.mMaxColumn = max (self.mMaxColumn, Column)
End Sub
Sub InsertFolder(row As Integer, text As String, Optional indent As Integer=0)
super.InsertFolder(row, text, indent)
call setRowData(row, true, indent)
End Sub
Sub InsertRow(row As Integer, text As String, Optional indent As Integer=0)
super.InsertRow(row, text, indent)
call setRowData(row, false, indent)
End Sub
Function RowIsFolder(row as integer) As Boolean
Dim isFolder as Boolean
Dim x(2) as variant

if NOT (me is nil) Then
// First. make sure the row is valid
if (( row >= 0) AND (row < me.ListCount)) then
x = Super.RowTag(row)
isFolder = x(1)
end if
end if

return isFolder
End Function
Sub RowIsFolder(row as integer, Assigns value As boolean)
Dim indent as integer
Dim x(2) as variant

if NOT (me is nil) Then
// First. make sure the row is valid
if (( row >= 0) AND (row < me.ListCount)) then
x = Super.RowTag(row)

  // Check original row, if already the proper mode, don't change
  if NOT (x(1) = value) Then
    
    x(1) = value
    
    // Get indent level
    indent =  x(2)
    
    // Add a new row before the currrent row
    if value then
      me.InsertFolder(row, "", indent)
    else
      me.Insertrow(row, "", indent)
    end if
    
    // Move all cell data and celltags to new row
    Super.RowTag(row) = Super.RowTag(row + 1)
    
    Dim maxColumn as integer
    Dim column as integer
    maxColumn = max(me.ColumnCount - 1, me.mMaxColumn)
    for column = 0 to maxColumn
      me.Cell(row, column) = me.Cell(row + 1, column)
      me.CellTag(row, column) = me.CellTag(row + 1, column)
    next column
    
    // Delete original row
    me.RemoveRow(row + 1)
  end if
end if

end if
End Sub
Function RowTag(row As Integer) As variant
// Create a variant array to store in rowTag
Dim x(1) as variant

// 0 = RowTag; 1 = IsFolder; 2 = Indent;
x = super.RowTag(row)
return x(0)
End Function
Sub RowTag(row As Integer, Assigns _value As Variant)
// Create a variant array to store in rowTag
Dim x(1) as variant

// 0 = RowTag; 1 = IsFolder; 2 = Indent;
x = super.RowTag(row)
x(0) = _value
End Sub
Private Sub setRowData(row as integer, isFolder as boolean, Optional indent As Integer=0)
// Create a variant array to store in rowTag
Dim x(2) as variant

x(1) = isFolder
x(2) = indent

super.RowTag(row) = x
End Sub
Private mMaxColumn As Integer
[/code]

Thanks for the assistance.