I can't find the bottom of the last row in listbox

I’m trying to add a “drop shadow” effect to the bottom of a listbox. I can draw the “shadow” image to a picture object. But I’m struggling to place the image so it lands in the right spot (the last the last 5 pixels of the row). The image is 5 pixels tall and the width of the listbox. Any suggestions?

In CellTextPaint, you get a g as graphics parameter. The y coordinate for placing that shadow picture, p, would presumably be:

y = g.height - p.height

Thank you that makes sense. I was thinking I would have to find whats visible on my own. (complicating things)

The height of G as Graphics is only whats visible. Is that correct?

Actually, incorrect. Let’s say a row is 20 pixels high, but only 4 pixels are visible because of scrolling. g will still be 20 pixels high. Presumably, you’re actually drawing into an offscreen buffer, which is blitted to the screen as needed.

You may find that it is better to use the cellbackgroud paint event. I don’t believe that the graphic of the celltextpaint is the full size of the cell. I believe that this is done to avoid text abutting tight to the edges of the cell. There was a discussion a few days ago where someone was trying to fill an entire cell with color in the text paint event only to find that it did not fully fill the cell.

In cellbackgroundpaint you can check

if row=me.listcount then
//draw to g
return true
end if

[quote=78215:@jim mckay]In cellbackgroundpaint you can check

if row=me.listcount-1 then
//draw to g
return true
end if[/quote]

Row is ZERO bases… ListCount is ONE based

right, so if he wants to draw into the first empty row…
if row=me.listcount then
//this is the row below the last row!
end if

Thanks for your help. Sorry for just getting back to this. Me.listcount puts the image in the last row in the listbox not the last visible row which is what I’m looking for.

[quote=78188:@Brad Hutchings]In CellTextPaint, you get a g as graphics parameter. The y coordinate for placing that shadow picture, p, would presumably be:

y = g.height - p.height

Brad’s idea works most of the time. I cannot tell why but when the window is scaled to specific sizes, the picture doesn’t display at all.

Check out the attached pictures:



(Edit) Displaying the pictures failed so I am including the link to the dropbox files…

Correct me if I’m wrong, but it looks like you just want a dropshadow around the listbox… if that’s the case, you could just place the listbox inside a canvas that’s slightly larger than the listbox and draw the shadow in the canvas.

Like so…

Jim yes you are correct. I want a drop shadow around the listbox. But for the listbox subclass I am trying to create, I would like to keep all the drawing inside the cells.

So your drop shadow would fall inside the listbox border? I don’t see how you would ever get a drop shadow around the listbox itself from within the listbox.

I have used two solutions for a similar issue:

  • put the listbox in a - slightly larger - ContainerControl and paint the shadow in there in the ContainerControl’s Paint() event.
  • if you are alsways using a subclass of Window in your application, loop over all listboxes in the window’s subclass Open() event, resize the listboxes to be a bit smaller and paint the shadow in the window’s Paint() event.

Right. Whatever you do will require the cooperation of the listbox’ parent.

I would personally go with the container…

But to answer the original question…
You can find how much of the last row is visible and draw accordingly. You may have to draw in the second to last row also to get the effect you’re looking for…

  dim VisibleRows as Double=(me.Height-me.HeaderHeight-me.RowHeight)/me.RowHeight
  dim DecimalPart As Double= VisibleRows-floor(VisibleRows)
  if row=floor(VisibleRows) then
    //  last fully visible row
  end if
  if row=ceil(VisibleRows) then
    // last partially visible row
  end if