listbox hierarchical

Is there a way to know which level of a hiearchical listbox was clicked?

You mean the indent amount? That isn’t there but easy to add in a subclass.

no, If i have three levels in my hiearchy, how can I determine which level was clicked on?

levels like this… each expansion a deeper level

level0 |-level1 |-level1 | |-level2 |-level1 level0 level0

Correct, but when I person clicks on say Level 2, how do I know what that level is…

I have 3 levels, first - Hospital, second - Instrument and the third level is the specimen type and I need to know which level they are clicking on so I can present different information…

I’m actually storing the record id in there, but I think i figured out a way…I added a column and stored the level in that, and then set the column width to 0%. Seems to work just fine for my purposes. Thanks

No need to do that, you can store info in columns that are not visible - if you have 3 columns visible in your listbox, you can still access columns 4 and up. (at least, that is how it worked in RS)

Also, in addition to the RowTag, you can store info in each cell’s CellTag.

I personally don’t like storing in invisible rows. Feels like a hack (although I’m sure it’s supported).

What I do is store the record as a class in the rowtag, while storing individual cell values as celltags for each. In the class object for each record I add properties I need and I can set those clases to update the database if changed as needed.

FWIW here’s a class that supplies row indent and whether it’s a folder. Trying to manage these datas in setup code I find too fiddly and error prone.

It works by overriding InsertFolder, InsertRow, AddFolder and both AddRows to store the datas in a Variant array in the real RowTag. RowIndent and RowIsFolder pull from that and it’s extended to store the users RowTag. The code is redundant to be quicker/inline-like.

[code]Class ListboxWithIndentAndIsFolder Inherits Listbox

Event ExpandRow(row As integer) //Event Definition
Sub ()

Sub ExpandRow(row As Integer) //Event Handler
indentWhenAdding = RowIndent(row) + 1
RaiseEvent ExpandRow(row)
indentWhenAdding = 0
End Sub

Private indentWhenAdding As Integer = 0 //Property

//=============== override methods to store indent and isFolder
Sub InsertFolder(row As Integer, text As String, indent As Integer = 0)
Super.InsertFolder(row, text, indent)
dim va(1) As Variant
va(0) = indent
va(1) = true
Super.RowTag(row) = va
End Sub

Sub InsertRow(row As Integer, text As String, indent As Integer = 0)
Super.InsertRow(row, text, indent)
dim va(1) As Variant
va(0) = indent
va(1) = false
Super.RowTag(row) = va
End Sub

Sub AddFolder(Text As String)
Super.AddFolder(Text)
dim va(1) As Variant
va(0) = indentWhenAdding
va(1) = true
Super.RowTag(LastIndex) = va
End Sub

Sub AddRow(items() As String)
Super.AddRow(items)
dim va(1) As Variant
va(0) = indentWhenAdding
va(1) = false
Super.RowTag(LastIndex) = va
End Sub

Sub AddRow(ParamArray item As String)
Super.AddRow(items)
dim va(1) As Variant
va(0) = indentWhenAdding
va(1) = false
Super.RowTag(LastIndex) = va
End Sub

//============= retrieve the new datas
Function RowIndent(row As integer) As Integer
dim va() As Variant = Super.RowTag(row)
return va(0)
End Function

Function RowIsFolder(row As integer) As boolean
dim va() As Variant = Super.RowTag(row)
return va(1)
End Function

//============= and override RowTag to use index 2
Function RowTag(row As Integer) As Variant
dim va() As Variant = Super.RowTag(row)
if va.Ubound = 2 then return va(2) //change to >= if adding RowTagN
return nil
End Function

Sub RowTag(row As Integer, Assigns _value As Variant)
dim va() As Variant = Super.RowTag(row)
if va.Ubound = 1 then redim va(2) //size up
va(2) = _value
End Sub

End Class[/code]

And you can extend the array with more RowTags, a dictionary or whatever. I use CellTags for decoration, RowTag for the represented instance and RowTagN for any meta datas.

[code] Function RowTagN(row As Integer, idx As integer) As Variant
if idx < 0 then return nil
dim va() As Variant = Super.RowTag(row)
idx = idx + 3
if va.Ubound >= idx then return va(idx)
return nil
End Function

Sub RowTagN(row As Integer, idx As integer, Assigns _value As Variant)
if idx < 0 then return //prevent data trashing
dim va() As Variant = Super.RowTag(row)
idx = idx + 3
if va.Ubound < idx then redim va(idx) //size up
va(idx) = _value
End Sub[/code]

How do I import Doofus’ code?