Jump to content
  • Advertisement
Sign in to follow this  
soconne

[.net] C# .NET listbox Invalidate not working

This topic is 4241 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a ListBox where each item is custom drawn with variable heights. A part of the item contains a number which must be updated every few cycles, but I cannot figure out how to correctly cause the listbox to update that portion. What I have tried is in the listbox's OnDrawItem method I have the following:
if(!updatingInfo) {
    // render each item as usual
}
else {
    // render only portion relevant to changed data

    // if we're on the last item, get out of updating info mode
    if(e.Index == listbox.Items.Count - 1) updatingInfo = false;
}

Then in my timer code I simply do:
updatingInfo = true;
listBox.Invalidate(new Region(new Rectangle(0, 0, 1, 1)));

Now the above invalidate does not work. It won't invalidate the control properly. But if I simply call listBox.Invalidate() with no parameters, it does work but the entire control blinks really bad. That is why I want to only call Invalidate on the upper left pixel but at the same time get the control to re-render the text at certain positions in each item. Is this possible? Here is a screenshot of the custom drawn listbox. The red circles indicate the regions I need to update every few cycles. Free Image Hosting at www.ImageShack.us

Share this post


Link to post
Share on other sites
Advertisement
You have answered your own question.
Quote:

call Invalidate on the upper left pixel

All painting/drawing that is performed in response to the Invalidate is clipped to the area that is invalid - the Graphics.Clip defines this rectangle and no pixels outside this rectangle will be overwritten. The way the list box has been implemented in .Net, it will always flicker on update. If you want to avoid the really bad flickering, use:

ListBox.Invalidate (ListBox.GetItemRectangle (index))

where index is the index of the item to redraw.

To get rid of the flickering totally, you need to create your own list box control derived from UserControl (not ListBox since the rendering of the ListBox is different to all other .Net controls).

Skizz

EDIT: If you use the above redraw method, your OnDrawItem event handler does not need any special code other than the code to draw the item.

Share this post


Link to post
Share on other sites
You should invalidate the whole control, but make the control be double-buffered. This way it rendered everything to a bitmap image and then draws that bitmap image to the screen. That should eliminate the flicker.

I assume you've created this as a UserControl. You should have a look at putting this.Setstyle(Controlstyles.OptimizedDoubleBuffer) in your constructor. You should probably set AllPaintingInWmPaint and UserPaint as well.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!