ListBox row selection problem


// code in the method executed on Window Open event to populate the ListBox

  dim i              As Integer
  dim sRecID         As String
  dim iRecID         As Integer
  dim sFirstName     As String
  dim sLastName      As String
  dim sName          As String
  dim sLodge         As String
  dim sErrMsg        As String 
  
  sSQL = "SELECT * FROM Masons"
  rsRecall = dbSQL.SQLSelect(sSQL)
  if dbSQL.Error then
    MsgBox(dbSQL.ErrorMessage)
    sErrMsg = "DATABASE ERROR - " + dbSQL.ErrorMessage
    UpdateLog("wMasons.PopulateListBox", sErrMsg)
    quit
    Return
  end if
  
  rsRecall.MoveFirst
  iCurrentRecord = rsRecall.Field( "pkRecID" ).IntegerValue
  
  lbMasons.deleteAllRows
  
  i = 0
  while not rsRecall.eof
    iRecID        = rsRecall.Field( "pkRecID" ).IntegerValue
    sFirstName    = rsRecall.Field( "GoesByName" ).StringValue
    sLastName     = rsRecall.Field( "LastName" ).StringValue
    sName         = sLastName + ", " + sFirstName
    sLodge        = rsRecall.Field( "fkHomeLodge" ).StringValue
    lbMasons.addRow "1"
    lbMasons.cell( i, 0 ) = str(iRecID)
    lbMasons.cell( i, 1 ) = sName
    lbMasons.cell( i, 2 ) = sLodge
    i = i + 1
    rsRecall.MoveNext
  wend
  

//Code in the DoubleClick Event of the ListBox  
//Have also used the same code in the MouseDown event

  dim iRow       As Integer
  dim sMasonID   As String
  dim sName      As String
  
  iRow      = Me.RowFromXY(System.MouseX - Me.Left - Self.Left, System.MouseY - Me.Top - Self.Top)
  sMasonID  = lbMasons.cell( iRow, 0 )
  sName     = lbMasons.cell( iRow, 1 )
  
  tfMasonIDTest.Text   = sMasonID
  tfMasonNameTest.Text = sName
  tfRowTest.Text       = str(iRow)
  
  //GoToRecord(sMasonID)
  //TabPanel1.Value = 0
  //PopulateDataEntryFields
  
  return

I have a problem I can not get my head around. I have a very simple listbox with 3 columns. The table it is being loaded from has a total of 16 records.

The top code block above is executed on window open to populate the listbox from the records in the table - appears to work properly.
The lower code block is executed in the doubleclick event of the listbox.
The desired result of a double click is to go to the corresponding record which was clicked on, populate the TextFields on the main panel and then to move from the panel with the listbox to the main panel with the editing fields.
The 3 lines commented out are the desired end result of a double click. The 3 lines above them populate textfields on the same panel with the listbox just to test and look at what is happening.

BUT… When I double click a row, the resulting data indicates I clicked on row + 1 and further the selected record is then 1 past that. In other words, I click on the top row (row 0), the iRow shows 1, but the selected record is the 3rd row.

Even stranger, when I put a debug mark and watch the execution in the debugger. then iRow ALWAYS results in 0, regardless of which row is clicked.

No matter which row I click on, the record 2 rows down is selected. I even created a new list box from scratch but on the same panel and used the same method to populate it. It does the same thing.

On the main panel of the tabcontrol (with the detailed data entry fields) I have navigation buttons that go to first, next, previous, and last records. This works fine.

Is there a possibility that the table is corrupted? Should I create a new table and then copy the data to the new table?

Someone PLEASE explain what’s going on.

thanks,
Bill

Try putting your record ID in RowTag as an Integer, then retrieve it with:

iMasonID = lbMasons.Rowtag( iRow )

There may be some kind of conversion problem going to the ListBox cell and backout as a string.

Do you happen to have placed the Listbox on a container control?
If yes, I guess the problem is that ‘Self’ (in: Me.RowFromXY(System.MouseX - Me.Left - Self.Left, System.MouseY - Me.Top - Self.Top)) is referring to the container control instead of the window.

As a test, see if it’s selecting the correct row if you place the container control at 0,0.

Marco, you make an interesting point which I will definitely test.

As for both your suggestion and Merv’s, they sound like sound things to test, which I will. The weird thing is this is the standard way I use listboxes to select records to edit. Something is just strange here.

I don’t remember if you were in the other thread where I talked about this (if so I apologize). I don’t think you need to go through the hoops you’re doing to get the row in the double click event. You can simply use the ListIndex that is set when the user clicks the first time on the row.

I’ve heard that it’s possible for it to not work correctly, but I’ve never seen it happen in practical use (that is unless you have code that changes the list index). You might want to try that because it seems like you’re fighting the control when it already has the value you want.

iRow = lbMasons.listindex sMasonID = lbMasons.cell( iRow, 0 ) sName = lbMasons.cell( iRow, 1 )

Anyway, my two cents worth of advice.

True.
Well, in case you need the Left and Top of a Control that’s on a container, maybe these extends will help.
(Add to a module)

[code]Function trueLeft(Extends rect As RectControl) As Integer
// Returns True Left
Dim iLeft As Integer = rect.Left

// Loop up the containers
Dim theWindow As Window = rect.Window
While theWindow IsA ContainerControl
iLeft = iLeft + theWindow.Left
theWindow = ContainerControl(theWindow).Window
Wend

// Return
Return iLeft + theWindow.Left

End Function
[/code]
and

[code]Function trueTop(Extends rect As RectControl) As Integer
// Returns True Top
Dim iTop As Integer = rect.Top

// Loop up the containers
Dim theWindow As Window = rect.Window
While theWindow IsA ContainerControl
iTop = iTop + theWindow.Top
theWindow = ContainerControl(theWindow).Window
Wend

// Return
Return iTop + theWindow.Top

End Function
[/code]

And then replace:

iRow = Me.RowFromXY(System.MouseX - Me.Left - Self.Left, System.MouseY - Me.Top - Self.Top)

with

iRow = Me.RowFromXY(System.MouseX - Me.trueLeft, System.MouseY - Me.trueTop)

The above extends should return the system Left/Top of the control.
I think you could use Self.TrueWindow.Left/Top or Me.TrueWindow.Left/Top as well but I was never able to figure out how to do that.