OutOfBoundException on listbox ghost row at the end

Helle everyone,

Below you will find the code which is in the “Open” event handler of the form listbox “lstSymbol” is in. I cannot find any errors inside this code.

The following code is in the “Change” event of listbox “lstSymbol” :

// Select User Symbol self.intUserSymbol = self.lstSymbol.RowTag(self.lstSymbol.ListIndex)

These are the only two places where listbox “lstSymbol” is created or accessed by code. Nowhere else is anything done with the listbox.

I found out that after the last row in the listbox, there appear a blank “ghost” row which is NOT added by my code. I can fill a listbox in a test project and when running there is no “ghost” row after the last one added.

When I do a lstSymbol.RemoveRow(lstSymbol.LastIndex)) it removes the last added row, not the Ghost row which is actually the last row.

I checked everything but cannot find anything. The listbox has no header.

I am searching this error by my own coding. I know I made a mistake somewhere along the line but fail to see where.

Do you know what is going wrong here and how I can solve it?

Thank you very much for your efforts spend on my problem, which is very much appreciated.

Wish you all a happy and healthy New Year!

Friendly greetings,

Chris

[code] // Creating object array clssBCSsymbols
// which contain the symbols with which
// the listbox lstSymbol is filled.

// Element 0
intPTRsymbol = 0
ReDim clssBCSsymbols(intPTRsymbol)
self.clssBCSsymbols(intPTRsymbol) = New clsBCSsymbols
self.clssBCSsymbols(intPTRsymbol).intID = intPTRsymbol
self.clssBCSsymbols(intPTRsymbol).strDescription = “Bee”
self.clssBCSsymbols(intPTRsymbol).picImage = imgBee
self.clssBCSsymbols(intPTRsymbol).picImage_32 = imgBee_32
// Next object 1
intPTRsymbol = intPTRsymbol + 1
ReDim clssBCSsymbols(intPTRsymbol)
self.clssBCSsymbols(intPTRsymbol) = New clsBCSsymbols
self.clssBCSsymbols(intPTRsymbol).intID = intPTRsymbol
self.clssBCSsymbols(intPTRsymbol).strDescription = “Chicken”
self.clssBCSsymbols(intPTRsymbol).picImage = imgChicken
self.clssBCSsymbols(intPTRsymbol).picImage_32 = imgChicken_32
// Next object 2
intPTRsymbol = intPTRsymbol + 1
ReDim clssBCSsymbols(intPTRsymbol)
self.clssBCSsymbols(intPTRsymbol) = New clsBCSsymbols
self.clssBCSsymbols(intPTRsymbol).intID = intPTRsymbol
self.clssBCSsymbols(intPTRsymbol).strDescription = “Crocodile”
self.clssBCSsymbols(intPTRsymbol).picImage = imgCrocodile
self.clssBCSsymbols(intPTRsymbol).picImage_32 = imgCrocodile_32
// Next object 3
intPTRsymbol = intPTRsymbol + 1
ReDim clssBCSsymbols(intPTRsymbol)
self.clssBCSsymbols(intPTRsymbol) = New clsBCSsymbols
self.clssBCSsymbols(intPTRsymbol).intID = intPTRsymbol
self.clssBCSsymbols(intPTRsymbol).strDescription = “Dog”
self.clssBCSsymbols(intPTRsymbol).picImage = imgDog
self.clssBCSsymbols(intPTRsymbol).picImage_32 = imgDog_32
// Next object 4
intPTRsymbol = intPTRsymbol + 1
ReDim clssBCSsymbols(intPTRsymbol)
self.clssBCSsymbols(intPTRsymbol) = New clsBCSsymbols
self.clssBCSsymbols(intPTRsymbol).intID = intPTRsymbol
self.clssBCSsymbols(intPTRsymbol).strDescription = “Dove”
self.clssBCSsymbols(intPTRsymbol).picImage = imgDove
self.clssBCSsymbols(intPTRsymbol).picImage_32 = imgDove_32
// Next object 5
intPTRsymbol = intPTRsymbol + 1
ReDim clssBCSsymbols(intPTRsymbol)
self.clssBCSsymbols(intPTRsymbol) = New clsBCSsymbols
self.clssBCSsymbols(intPTRsymbol).intID = intPTRsymbol
self.clssBCSsymbols(intPTRsymbol).strDescription = “Elephant”
self.clssBCSsymbols(intPTRsymbol).picImage = imgElephant
self.clssBCSsymbols(intPTRsymbol).picImage_32 = imgElephant_32
// Next object 6
intPTRsymbol = intPTRsymbol + 1
ReDim clssBCSsymbols(intPTRsymbol)
self.clssBCSsymbols(intPTRsymbol) = New clsBCSsymbols
self.clssBCSsymbols(intPTRsymbol).intID = intPTRsymbol
self.clssBCSsymbols(intPTRsymbol).strDescription = “Fish”
self.clssBCSsymbols(intPTRsymbol).picImage = imgFish
self.clssBCSsymbols(intPTRsymbol).picImage_32 = imgFish_32
// Next object 7
intPTRsymbol = intPTRsymbol + 1
ReDim clssBCSsymbols(intPTRsymbol)
self.clssBCSsymbols(intPTRsymbol) = New clsBCSsymbols
self.clssBCSsymbols(intPTRsymbol).intID = intPTRsymbol
self.clssBCSsymbols(intPTRsymbol).strDescription = “Frog”
self.clssBCSsymbols(intPTRsymbol).picImage = imgFrog
self.clssBCSsymbols(intPTRsymbol).picImage_32 = imgFrog_32
// Next object 8
intPTRsymbol = intPTRsymbol + 1
ReDim clssBCSsymbols(intPTRsymbol)
self.clssBCSsymbols(intPTRsymbol) = New clsBCSsymbols
self.clssBCSsymbols(intPTRsymbol).intID = intPTRsymbol
self.clssBCSsymbols(intPTRsymbol).strDescription = “Giraffe”
self.clssBCSsymbols(intPTRsymbol).picImage = imgGiraffe
self.clssBCSsymbols(intPTRsymbol).picImage_32 = imgGiraffe_32
// Next object 9
intPTRsymbol = intPTRsymbol + 1
ReDim clssBCSsymbols(intPTRsymbol)
self.clssBCSsymbols(intPTRsymbol) = New clsBCSsymbols
self.clssBCSsymbols(intPTRsymbol).intID = intPTRsymbol
self.clssBCSsymbols(intPTRsymbol).strDescription = “Lion”
self.clssBCSsymbols(intPTRsymbol).picImage = imgLion
self.clssBCSsymbols(intPTRsymbol).picImage_32 = imgLion_32
// Next object 10
intPTRsymbol = intPTRsymbol + 1
ReDim clssBCSsymbols(intPTRsymbol)
self.clssBCSsymbols(intPTRsymbol) = New clsBCSsymbols
self.clssBCSsymbols(intPTRsymbol).intID = intPTRsymbol
self.clssBCSsymbols(intPTRsymbol).strDescription = “Owl”
self.clssBCSsymbols(intPTRsymbol).picImage = imgOwl
self.clssBCSsymbols(intPTRsymbol).picImage_32 = imgOwl_32
// Next object 11
intPTRsymbol = intPTRsymbol + 1
ReDim clssBCSsymbols(intPTRsymbol)
self.clssBCSsymbols(intPTRsymbol) = New clsBCSsymbols
self.clssBCSsymbols(intPTRsymbol).intID = intPTRsymbol
self.clssBCSsymbols(intPTRsymbol).strDescription = “Penguin”
self.clssBCSsymbols(intPTRsymbol).picImage = imgPenguin
self.clssBCSsymbols(intPTRsymbol).picImage_32 = imgPenguin_32
// Next object 12
intPTRsymbol = intPTRsymbol + 1
ReDim clssBCSsymbols(intPTRsymbol)
self.clssBCSsymbols(intPTRsymbol) = New clsBCSsymbols
self.clssBCSsymbols(intPTRsymbol).intID = intPTRsymbol
self.clssBCSsymbols(intPTRsymbol).strDescription = “Salamander”
self.clssBCSsymbols(intPTRsymbol).picImage = imgSalamander
self.clssBCSsymbols(intPTRsymbol).picImage_32 = imgSalamander_32
// Next object 13
intPTRsymbol = intPTRsymbol + 1
ReDim clssBCSsymbols(intPTRsymbol)
self.clssBCSsymbols(intPTRsymbol) = New clsBCSsymbols
self.clssBCSsymbols(intPTRsymbol).intID = intPTRsymbol
self.clssBCSsymbols(intPTRsymbol).strDescription = “Snake”
self.clssBCSsymbols(intPTRsymbol).picImage = imgSnake
self.clssBCSsymbols(intPTRsymbol).picImage_32 = imgSnake_32
// Next object 14
intPTRsymbol = intPTRsymbol + 1
ReDim clssBCSsymbols(intPTRsymbol)
self.clssBCSsymbols(intPTRsymbol) = New clsBCSsymbols
self.clssBCSsymbols(intPTRsymbol).intID = intPTRsymbol
self.clssBCSsymbols(intPTRsymbol).strDescription = “Spider”
self.clssBCSsymbols(intPTRsymbol).picImage = imgSpider
self.clssBCSsymbols(intPTRsymbol).picImage_32 = imgSpider_32
// Next object 15
intPTRsymbol = intPTRsymbol + 1
ReDim clssBCSsymbols(intPTRsymbol)
self.clssBCSsymbols(intPTRsymbol) = New clsBCSsymbols
self.clssBCSsymbols(intPTRsymbol).intID = intPTRsymbol
self.clssBCSsymbols(intPTRsymbol).strDescription = “Starfish”
self.clssBCSsymbols(intPTRsymbol).picImage = imgStarFish
self.clssBCSsymbols(intPTRsymbol).picImage_32 = imgStarFish_32
// Next object 16
intPTRsymbol = intPTRsymbol + 1
ReDim clssBCSsymbols(intPTRsymbol)
self.clssBCSsymbols(intPTRsymbol) = New clsBCSsymbols
self.clssBCSsymbols(intPTRsymbol).intID = intPTRsymbol
self.clssBCSsymbols(intPTRsymbol).strDescription = “Whale”
self.clssBCSsymbols(intPTRsymbol).picImage = imgWhale
self.clssBCSsymbols(intPTRsymbol).picImage_32 = imgWhale_32
intTotElements = UBound(self.clssBCSsymbols)

// Fill lstSymbol with images and descriptions
// Clear listbox lstSymbol
self.lstSymbol.DeleteAllRows
self.lstSymbol.ColumnWidths = “40, *”
For i = 0 To intTotElements
self.lstSymbol.AddRow “”
self.lstSymbol.RowTag(i) = clssBCSsymbols(i).intID
self.lstSymbol.RowPicture(i) = clssBCSsymbols(i).picImage_32
self.lstSymbol.Cell(i, 1) = self.clssBCSsymbols(i).strDescription
Next i[/code]

first off… don’t keep redimming… just use APPEND… much faster… and tons less memory overhead

temp= New clsBCSsymbols
temp.intID = intPTRsymbol
temp.strDescription = "Whale"
temp..picImage = imgWhale
temp..picImage_32 = imgWhale_32
 clssBCSsymbols.append temp

no need for intPTRSymbol… and the rest just may sort itself out for you

Hello Dave,

Thank you very much for giving me a much cleaner way to code a class array. I just changed my code and I agree it is much better than what I was using. I appreciate your suggestion very much.

However the error at the listbox remains, the ghost row is still present. But at least the coding improved.

Wish you a very nice day and all the best.

Friendly greetings,

Chris

is there are difference between intTotElements and intPTRsymbol when you fill the listbox?

try

For i = 0 To intPTRsymbol

and although not the cause: in the change event, its usually a good idea to test that the list index is within the range of list items.

if me.listindex < me.listcount then self.intUserSymbol = me.RowTag(me.ListIndex)

Does your class contain anything other than a name and a picture?
If not, you probably don’t even need the class: everything you need is in the listbox, because intPTRsymbol is the same as the list index.

[code]lstSymbol.DeleteAllRows
lstSymbol.ColumnWidths = “40, *”
lstSymbol.AddRow “”
lstSymbol.RowPicture( lstSymbol.lastindex) = imgBee_32
lstSymbol.Cell(lstSymbol.lastindex,1) = “Bee”
lstSymbol.AddRow “”
lstSymbol.RowPicture( lstSymbol.lastindex) = imgChicken_32
lstSymbol.Cell(lstSymbol.lastindex, 1) = “Chicken”
//…etc

[/code]

and then you don’t even need that change code or the self.intUserSymbol variable.
Wherever you used that, it would become lstSymbol.listindex instead

Hello Jeff,

Thank you very much for your input. You are correct, there is nothing else in the class array than the text and the two images.

The property “intTotElements” is indeed not necessary.

But I found out which causes the ghost row in the listbox.

Look to the “Change” event of the listbox “lstSymbol” which is :

// Select User Symbol self.intUserSymbol = self.lstSymbol.RowTag(self.lstSymbol.ListIndex)

From the moment I add this line to the test project, I get the same “Ghost” line as in the original program.

However I fail to see what I am doing wrong here?

Anybody any idea what is wrong here?

Wish you all the best.

Friendly greetings,

Chris

Hello again,

I forgot but the class array is used to add more animals later when necessary. I just make a new entry and the content of the listbox adapt itself. That is why I prefer to store lists with more than 2 colums in a class array.

Thank you again.

Friendly greetings,

Chris

Hello everyone,

I found a workaround for my problem.

First, this is definatelly a bug in Xojo. I have no idea why, but the line in the “Change” event code, adds the Ghostline even when it is not supposed to do so.

This is how I solved it :

First expanded listbox “lstSymbols” with an extra row.
lstSymbols.Columncount = 3

Then I changed the code inside the “Open” event handler of the form to this :

[code]// Fill lstSymbol with images and descriptions
// Clear listbox lstSymbol
self.lstSymbol.DeleteAllRows
self.lstSymbol.ColumnWidths = “40,0; *”
For i = 0 To intTotElements
self.lstSymbol.AddRow “”
self.lstSymbol.Cell(i, 1) = Str(clssBCSsymbols(i).intID)
//self.lstSymbol.RowTag(i) = clssBCSsymbols(i).intID
self.lstSymbol.RowPicture(i) = clssBCSsymbols(i).picImage_32
self.lstSymbol.Cell(i, 2) = self.clssBCSsymbols(i).strDescription
Next i

// Select a symbol
self.lstSymbol.ListIndex = 0
[/code]

Then inside the “Change” event of listbox “lstSymbols” I used the following line :

// Select User Symbol self.intUserSymbol = Val(self.lstSymbol.Cell(me.ListIndex, 1))

Which does not prevent the ghostline from showing up and when clicked it gives the first symbol in the listbox but at least the OutOfBoundsException error is gone.

What I did was by creating an extra column, in column 0 there is the rowpicture, in column 1 there is the Index number which is invisible because I set the wide to 0 and in Column 2 there is the descriptive text.

That is it.

For me this workaround is acceptable because it is only a small game (Tic-Tac-Toe) for my little daughter.

But in case this is a bug, Xojo inc should fix it. I cannot send any feedback report because the internet connection is not good here in Botswana.

I want to thank everyone who contributed to my question. Finally your replies lead me to this workaround for my problem.

Wish you all a very nice New Year!

Friendly greetings,

Chris

Hi Chris – not sure what you mean by “ghost row” or what’s causing that, but you’ve posted a lot of code and it’s a bit overwhelming to go through.

Another tip you might consider in order to simply this code is to add a Constructor method to your clsBCSsymbols class with the parameters of the properties you’re setting. Then instead of code like this:

self.clssBCSsymbols(intPTRsymbol) = New clsBCSsymbols self.clssBCSsymbols(intPTRsymbol).intID = intPTRsymbol self.clssBCSsymbols(intPTRsymbol).strDescription = "Bee" self.clssBCSsymbols(intPTRsymbol).picImage = imgBee self.clssBCSsymbols(intPTRsymbol).picImage_32 = imgBee_32

You’d just have one line like this:

self.clssBCSsymbols(intPTRsymbol) = New clsBCSsymbols(intPTRsymbol,  "Bee", imgBee, imgBee_32)

That’s a lot easier to read and parse (and it saves you typing).

Any time you see yourself repeating code it’s a good idea to consider putting the code into a method.

Hello Marc,

Thank you very much for your suggestion, which is great.

I changed the code accordingly to your suggestion and it is indeed much clearer than what I submitted.

I also do not know why that “ghost” row appears, but it has to do with the ListIndex in combination with the RowTag property inside the change event of the listbox.

The coding of the “Open” event of the form, seems now much nices after your suggestion. I appreciate your input very much.

wish you a very nice and healthy New Year and all the best.

Friendly greetings,

Chris

did you try this?

if me.listindex < me.listcount then self.intUserSymbol = me.RowTag(me.ListIndex)

ListIndex:
The selected item number. The index is zero-based.

Are-you sure that ListIndex is the property to use ?

Also, listIndex = -1 when nothing is selected. That may have been the source of your outofbounds exception.

Hello Jeff, Emile and Greg,

Thank you all for your replies and your suggestions.

I checked the total amound of rows with ListCount and it is 17 which is correct because Listcount is 1 based.

I also count the rows manually and I count 17, excluding the Ghost row.

I really wish and hope it is an error of mine, however I think it is a bug (not serious) because in the change event, the ListIndex property is only read.

The workaround above does not remove or prevent the ghost row, however the OutOfBoundException error is gone which is the most important fact. At least for me it is a workaround which works fine.

I appreciate your help very much. This is a very helpfull and skilled communty.

Since the initial release of Xojo there is a lot of improvement in speed and stability. I can see that the Xojo Inc team work hard to gives us a good RAD multi platform development tool. Very well done!!!

Wish you all a very good New Year, a good health and very much happiness!

Friendly greetings,

Chris