Archive for 9th June 2009

CodeStock 2009

CodeStock 2009 is rapidly approaching, and an associate of mine at the office is attending this year’s conference with me. If you happen to be attending the conference, and notice a loud troublemaker somewhere in the vicinity, it would be my associate. Just be careful giving your business card to him, he is likely to use one of them for his only phone call, as I told him that if he needed bail money, he is on his own.

VB.NET ListBox does not scroll all the way to the bottom when setting SelectedIndex

I have a standard Windows list box that I am using in my Visual Basic .NET application. I am adding records into this list box by binding it to a data source that reads records from a local database and uses a display member in the class to chew on the record and spit out the text. Then, I logically want to see if there are records in this newly minted list box, and if so, set the selection to the last record in the list, which should scroll to the bottom of the list in the event that there are more records to display than lines in the list box. The code:

lstRecords.DataSource = DataLayer.GetRecords(theID)
If lstRecords.Items.Count > 0 Then
    lstRecords.SelectedIndex = lstRecords.Items.Count - 1
End If

Unfortunately, this code does not work 100% as expected. If there are more records than rows available in the list box, the final row does get selected, as the blue selection bar lands on that row. Once you scroll the list down one row to see it. For some reason, the scrolling down of the list box comes up one row short when done this way, no matter how many rows beyond the limit of the list box are added.

I tried everything I could think of, mostly manipulating the properties of the list box to see if some combination worked. I called the Update and Refresh methods, set the TopIndex and IntegralHeight properties, and lots of other things that did not have any effect.

I finally decided to try to set the SelectedIndex property in a timer event. The timer is initially disabled with an interval of 5 ms, and instead of setting the SelectedIndex property as shown in the line above, it enables the timer. And here is the code that executes when the timer fires:

tmrScrollToEnd.Enabled = False
lstRecords.SelectedIndex = lstRecords.Items.Count - 1

And of course, for some reason that escapes me, this now works. Perhaps it is because the setting of the SelectedIndex is moved outside of the Form Load code, which is where the code above was being executed. If anyone has any ideas, I would love to hear them, but I am glad that it is now working.