Looking for ListBox.CellBackgroundPaint Hack

Hello,

has anyone ever managed to draw a picture across the entire width of a ListBox row by hacking, regardless of how many columns it has? My approach was to clear the background of all columns using ClearRect (macOS) and then draw the image in the first row, but the area is still limited to the column width. I also tried drawing the picture in the last column and using the negative width of all previous columns as x coordinate. Unfortunately this doesn’t work either.

CellBackgroundPaint

[code]If row = 0 Then
g.ClearRect(0, 0, g.Width, g.Height)
If column = 0 Then
Dim colors(2) As Pair
colors(0) = 0.0 : &c19191900
colors(1) = 0.5 : &cF2F2F200
colors(2) = 1.0 : &cF2F2F200

Dim p As Picture = CreateGradient(MyListBox.Width, g.Height, colors)
g.DrawPicture(p, 0, 0)

End If
End If[/code]

You should create and update a Picture with the full listbox’ width and column height during resized events and then do a drawpicture with the current portion of the cached picture in the cellBackgoundPaint event (in other words use the additional parameters to define the picture source area to copy from).

Yes, we made such a project at a training day…

That’s a very, very clever suggestion. Now I fail once more because of the DrawPicture parameters. For the first two columns the intermediate result looks quite good. With the remaining columns I probably fail again because of mathematics. Here my code - suggestions?

If column = 0 Then If Pic = Nil Then Pic= CreateGradient(Me.Width, Me.DefaultRowHeight, Colors) End If g.DrawPicture(Pic, 0, 0) Else g.DrawPicture(Pic, 0, 0, Me.Column(column).WidthActual, 21, Me.Column(column-1).WidthActual) ' wrong code End If

Yes. You have to sum up the actual widths of former columns when you calculate the offset, not only take the previous one’s.

Sorry, I’m just acting a little stupid… It looks like there is something wrong with my parameter passing in DrawPicture.

[code]Dim a As Integer
For i As Integer = 0 To column - 1
a = a + Me.Column(i).WidthActual
Next

g.DrawPicture(Pic, 0, 0, Me.Column(column).WidthActual, 21, a) ’ ???[/code]

Looks good. Doesn’t it work?

EDIT: Err, probably

For i As Integer = 0 To column - 1

Looks better, but not clean.

That’s with or without -1?

Sorry?

Yes is is possible with some work. The garden picture in the cells here is drawn across both columns and rows:

[quote=459389:@Ulrich Bogun]EDIT: Err, probably
For i As Integer = 0 To column - 1
[/quote]

Step by step in the right direction, but not yet arrived…

[code]Dim a As Integer
For i As Integer = 0 To column - 1
a = a + Me.Column(i).WidthActual
Next

g.DrawPicture(Pic, 0, 0, Me.Column(column).WidthActual, 21, a) ’ ???[/code]

In cases like this, I tend to insert System.DebugLog() statements to review instead of debug breakpoints. Something like:

#If DebugBuild
  System.DebugLog("Draw " + str(row) +  "," + str(column) + " from" + str(a) + " width " + str(Me.Column(column).WidthActual))
#Endif

Then you can quickly look down the log and make sure the numbers make sense. Way faster than breakpoints, and does not impact the UI while doing it.

I suspect that may help narrow the cause.

I did not check the documentation. it is

Graphics.DrawPicture(Image As Picture, x As Double, y As Double [,destWidth As Double ] [, destHeight As Double ] [, sourceX As Double ] [, sourceY As Double ] [, sourceWidth As Double ] [, sourceHeight As Double])

So the code should rather be

g.DrawPicture(Pic, 0, 0, g.width, g.height, a, 0, g.width, g.height)

I guess :wink:

The Padawan thanks his master. You made my night :wink:

[code]Dim offset As Integer

For i As Integer = 0 To column - 1
offset = offset + Me.Column(i).WidthActual
Next

g.DrawPicture(Pic, 0, 0, g.Width, g.Height, offset, 0, g.Width, g.Height)[/code]