How to crash the Listbox …

Well, I decided to file a bug report again - let’s see if it does any better than the previous ones:

OutOfBounds Exception in HeaderBackgroundPaint event as g.width is ZERO
<https://xojo.com/issue/61965>

All the code you need is

Dim p as new Picture(g.width, g.height)

in the HeaderBackgroundPaint event and you will get an OutOfBounds exception as g.width is 0.0

Setting the Listbox count to 1 and the width to 1* does not help, you need to set the Listbox width to a literal (eg 100).

Why is g.width ZERO in the first place???

Kind of cements my impression that the customisable header was a last minute addition and not well thought out and implemented.

If you set the Font size to 30 then the Header height will be 40. This is insane! How are you supposed to precisely set your header height? By guessing? Trial & error? Why not:

Fig 2 User-friendly header and row settings for the ListBox

After all, backwards compatibility has been thrown out of the window anyway, so why stop now?

And btw, you COULD implement this in a backward-compatible way - the Listbox has HeaderHeight and RowHeight properties since 2009 - but they are read only! Why not implement them as they should be implemented???

I’ll be damned - now it is no longer doing it.

Beats me why - I didn’t even restart, it is the same unchanged project.

And it’s back. I emptied the cache and then it was back - how???

I would understand if it was the other way round but this …???

I changed the code a bit and followed it in the debugger and the Exception happens on the second entry with column = 1

But there is only one column, column 0 - so of course g.width is zero, but that is not allowed.

Adding the following code at the top will solve the issue

If g is nil or g.width = 0 then return False

Yes - and returning True … comes from moving code from CellBackgroundPaint event (where I did not need to do that) to HeaderBackgroundPaint event (that absolutely requires it) - otherwise it paints over the background.

My thanks to Karen & Jeremy!

Why are you confusing me with Karen?

VERY bad memory for names …

I haven’t had this crash, but perhaps it’s because all I do in HeaderBackgroundPaint is return true. All my drawing/painting for the header is done in HeaderContentPaint.

I keep the essentially empty HeaderBackgroundPaint event because I serendipitily discovered that it causes the header stub above the top of the listbox scroll bar to be properly painted by HeaderContentPaint. Quite how it manages to do this I don’t know.

As I wrote in the feedback report, g.width doesn’t become 0 in HeaderTextPaint, so that works.

And yes, I have also run into the stub problem - in my case it is 15 pixel wide and I would guess that it is space reserved for the scrollbar. But I can’t reproduce it in a simple project started in 2020R1.1, so it might only affect Listboxes created in earlier versions. Will test that idea later.

It is definitely the scrollbar showing up in which case another column the width of the scrollbar is being added (which seems a really weird way of dealing with the problem - I would have thought the Listbox is more modular internally, maybe a ContainerControl that draws the header in the paint event of the ContainerControl and adds a scrollbar beside the rows if necessary).

If I use a hierarchical Listbox with all folders collapsed then I do not see the stub:

screenshot_149

but if I expand a folder and the scrollbar shows up then I see it:

screenshot_150

I can actually paint in the stub by doing

If g Is Nil Or g.width = 0 Then Return False

Me.CreatePictureOfGradient( g )
g.DrawPicture(Me.PictureOfGradient, 0, 0, g.width, g.height, 0, 0, 1, g.height)

If column < me.ColumnCount Then
  // do your other custom drawing 
end if 
Return True

screenshot_151

So the answer is:

If g Is Nil Or g.width = 0 Then Return False

// For the background I create a gradient that is 1 pixel wide and g.height high
Me.CreatePictureOfGradient( g ) 
// and paint that across g
g.DrawPicture(Me.PictureOfGradient, 0, 0, g.width, g.height, 0, 0, 1, g.height)

If column < me.ColumnCount Then
  // do your other custom drawing 
end if 
Return True

My thanks to Jeremy and BEATRIX (!) :hugs:

1 Like