Redraw flashing problem with ListView in virtual mode.

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

I am using the .Net 2.0 ListView control in virtual mode and am having some
unsightly re-draw/flashing problems. The listview control works quite well
in this mode when displaying and scrolling thousands of items. The re-draw
problem occurs when I insert a new item into the list. In this case I update
my data structures and then call the "VirtualSize" property on the control.
At this point three things can happen:
- Desired behavior - the listview redraws once (I see one WM_ERASEBKGND and
one WM_PAINT message each).
- Bad behavior - the listview redraws erases and redraws a few times and
causes unsightly flashing.
- Really bad behavior - the listview redraws many times (I see man
WM_ERASEBKGND and WM_PAINT messages), causing really bad re-draw experience.
The worst part is that a lot of the drawing is done outside the normal .Net
and windows message loop ... I intercept and eat WM_ERASEBKGND messages, the
BeginUpdate and EndUpdate calls are being ignored and I don't do any owner
drawing during this time.

Interestingly I can make the desired behavior occur if I select or sometimes
select and then clear items in the list. So this appears to be the ListView
control trying to restore the list position during the call to "VirtualSize".

Is there anyway I can fix or work around this problem? Ideally I want to be
able to a) change the list view virtual size, b) restore previous selections,
c) possibly change the scroll position, all with only a single redraw of the
list.

Thanks for any help.
 
Paul said:
I am using the .Net 2.0 ListView control in virtual mode and am having some
unsightly re-draw/flashing problems. The listview control works quite well
in this mode when displaying and scrolling thousands of items. The re-draw
problem occurs when I insert a new item into the list. In this case I update
my data structures and then call the "VirtualSize" property on the control.
At this point three things can happen:
- Desired behavior - the listview redraws once (I see one WM_ERASEBKGND and
one WM_PAINT message each).
- Bad behavior - the listview redraws erases and redraws a few times and
causes unsightly flashing.
- Really bad behavior - the listview redraws many times (I see man
WM_ERASEBKGND and WM_PAINT messages), causing really bad re-draw experience.
The worst part is that a lot of the drawing is done outside the normal .Net
and windows message loop ... I intercept and eat WM_ERASEBKGND messages, the
BeginUpdate and EndUpdate calls are being ignored and I don't do any owner
drawing during this time.

Interestingly I can make the desired behavior occur if I select or sometimes
select and then clear items in the list. So this appears to be the ListView
control trying to restore the list position during the call to "VirtualSize".

Is there anyway I can fix or work around this problem? Ideally I want to be
able to a) change the list view virtual size, b) restore previous selections,
c) possibly change the scroll position, all with only a single redraw of the
list.

Thanks for any help.
 
I don't know if you check this any more, but for anyone that stumbles across
this in the future, you can easily dodge this problem implementing a class
that inherits the ListView control and is tuned towards using the VirtualMode
(i.e. it handles the internal caching functions, my implementation requires
you to supply an event handler to populate a list item at a given index on
demand, that's it). In the constructor of this class, do this:

SetStyle(ControlStyles.OptimizedDoubleBuffer, true);

And the flickering is gone. What this does is, when the control paints
itself, it just draws a pre-rendered bitmap from a buffer. The control is
actually painted to an off-screen buffer in memory. When it is done painting
offscreen, this buffer is moved to the pre-rendered buffer which is used to
quickly paint the list (as it is simply copying the bitmap, as opposed to
drawing each item individually).
 
Back
Top