Populating a listbox

Hi all,

I’m a little stuck with something I’ve been testing and can’t work out why it’s not doing what I thought it would.

A simple window containing 2 listboxes, and a small test database with 4 rows.

The code below works perfectly to add the rows to Listbox1 using the usual method.

Then I have added additional code to populate Listbox2 within the same loop, with the intention of placing the text at specific co-ordinates, using the g.DrawString in the CellTextPaint event for Listbox2. The code is straight forward as below :

[code] Dim IncidentDB As New SQLiteDatabase

IncidentDB.DatabaseFile = GetFolderItem(“TestDB.sqlite”)

If Not IncidentDB.Connect Then
Msgbox(“Unable to connect to database”)
Else
Dim IncSet As RecordSet
Dim SQL As String = “Select * From TestData ORDER BY Incident”

IncSet = IncidentDB.SQLSelect(SQL)

If IncSet <> Nil Then
  
  While Not IncSet.EOF
    
    Listbox1.AddRow(IncSet.IdxField(2).StringValue)
    
    JobID=IncSet.IdxField(2).StringValue
    
    Listbox2.AddRow()
    
    IncSet.MoveNext
    
  Wend
  
End If

End If[/code]

JobID is set as a text property within a module.

When I run the program, this is the ouput :

The numbers in Listbox1 (Left) are correct, but Listbox 2 on the right only ever shows the last JobID value for every row; they should be identical to the ones on the left.

The CellTextPaint event for Listbox2 is:

g.DrawString JobID, 1, 17

I’ve also tried it using:

g.DrawString(JobID, 1, 17)

Also, for the Listbox2.AddRow, I’ve tried using:

Listbox2.AddRow
Listbox2.AddRow()
Listbox2.AddRow("")

But nothing seems to work. Data is being placed in JobID, and g.DrawString can see it, but it is not changing for each invocation of While… Wend.

I can’t think of any trigger or event that I’m missing.

Any thoughts folks ?

Thanks.

Your code assumes that the CellTextPaint event is called at a very precise time, which may not be true. Since the module property can only ever hold a single value, if the timing is off, unexpected values will get displayed. For example, perhaps CellTextPaint only gets called after the entire populate loop is finished.

You might consider instead saving the JobID in the CellTag for the row/column and then letting the event handler run at its usual time.

In your setup loop do something like this:

ListBox2.AddRow("") ListBox2.CellTag(ListBox2.LastIndex, 0) = IncSet.IdxField(2).StringValue
And in CellTextPaint:

g.DrawString(Me.CellTag(row, column).StringValue, 1, 17)

Edit: Fixed typo in code

Well I certainly did assume that the CellTextPaint event fires each time a row is added.

The cursor positioning within the recordset is correct too otherwise Listbox1 would be incorrect.

I see what you are saying with regards to using the CellTag, but how could I use more than one data field ?

I could theoretically concatenate them all into the CellTag, but parsing that every time would be inefficient I think.

Btw, changing lastrow to lastindex made your example work :slight_smile:

I think I’ve just worked out a way to do it using multiple fields.

Assuming we had say 5 columns in the database and want to display all 5 fields for each record:

Set listbox2 columncount to 5
Set the first column width to 100%
Set each Celltag with the field content as you described above

Then add multiple drawstring events, changing the x,y co-ordinates as required for positioning the text:

g.DrawString(Me.CellTag(row, column).StringValue, x, y)
g.DrawString(Me.CellTag(row, column+1).StringValue, x, y)
g.DrawString(Me.CellTag(row, column+2).StringValue, x, y)
g.DrawString(Me.CellTag(row, column+3).StringValue, x, y)
g.DrawString(Me.CellTag(row, column+4).StringValue, x, y)

In terms of execution time though, how efficient could the code above be considered ?

Don’t forget that you can put anything into a celltag… Including an object. You could put an array of values, or a class contains your values in there.

Yep, thanks Greg and Paul.

I’ve tried a second attempt using the methods above and all appears well :

This is exactly what I wanted, to simulate a multiline listbox :slight_smile:

It can’t possibly, because your code is still running. The listbox won’t be able to paint anything until after your loop finishes and the system gets a chance to refresh the screen.

Yep, I get that now. I assumed it ran as part of the addrow itself. All good now anyway.