Right. It took a while for that to sink in. I eventually decided to add some code to log all of the event handlers so that I could see the order in which they are triggered, and what their parameters are. That’s when I finally understood what you were saying. From a focus point of view, the cell is an independent entity from the listbox. So, when one has focus, then the other one doesn’t. I had initially assumed that cell focus was nested inside listbox focus.
When tabbing from an external control to the listbox, with my GotFocus handler code that jumps to cell(0,1), the Sequence of events is:
GotFocus
LostFocus
CellGotFocus (0, 1)
Then, when tabbing from cell to cell the sequence of events is:
KeyDown (0, 1)
CellAction (0, 1)
CellLostFocus (0, 1)
CellGotFocus (1, 1)
So, when tabbing between cells, there is no GotFocus/LostFocus for the listbox, just for the cells themselves.
When clicking directly into a cell with the mouse, this is what happens:
GotFocus
LostFocus
CellGotFocus (0, 1) (goes to cell (0,1) due to GotFocus code, regardless of the cell clicked on)
CellAction (0, 1) (exits edit mode of cell (0,1) due to CellClick event.)
CellLostFocus (0, 1) (leaves cell (0,1) due to CellClick event.)
CellClick (1, 1) (arrives at the cell that was actually clicked on.)
CellGotFocus (3, 1) (these parameters may be incorrect if the listbox scrolled due to the click.)
Note that the first three events are identical to what happens when tabbing into the listbox from an external control.
Also complicating things, when the GotFocus handler calls the EditCell method, that triggers the CellGotFocus event, and so the remaining code in the GotFocus handler is suspended until the cellGotFocus handler finishes.
Eventually, I figured that if I added a bit of code to the GotFocus handler to check the scroll position before and after calling EditCell method, and saving the difference as a scrollOffset property, the CellClick handler could use this value to correct the row number. This is the code that I ended up with:
Sub GotFocus() Handles GotFocus
dim sp As Integer = me.ScrollPosition
if cbAutoEdit.Value then
if me.LastIndex>=0 then
me.EditCell(0,1)
txArea2.AppendText " sp2="+str(me.ScrollPosition)+EndOfLine
scrollOffset=sp-me.ScrollPosition
end if
end if
End Sub
This is the revised CellClick handler code:
Function CellClick(row as Integer, column as Integer, x as Integer, y as Integer) Handles CellClick as Boolean
'Column 0 is not editable. Column 1 is editable
me.ScrollPosition=me.ScrollPosition+scrollOffset
if column=1 then
me.EditCell(row+scrollOffset,column)
else
me.ListIndex=me.ScrollPosition+scrollOffset
end if
End Function
This code is working now. When clicking on a cell, it still jumps to cell(0,1) first and then back to the clicked cell, but this happens too fast to see. It could possibly be a problem on a much longer list, but for my current project it shouldn’t be a problem. The only way I can see to prevent the unnecessary jumping to Cell(0,1) would be to add code to the preceding and succeeding controls’ event handlers, which I’d rather avoid.