First of, EndUpdate invalidates (i.e. redraws) the entire client area. It
doesn't matter if you changed anything or not, or what propertyvalues you're
using. BeginUpdate/EndUpdate isn't some universal solution that should
always be called. If you're not updating anything then don't use them! IMO
there is nothing wrong with this design
Scenario 1a, 2a, 3a: UseItemStyleForSubItems = True
The ListView and its content is drawn by Windows (inside the common control
libraries)
Windows uses GDI (same as VB6) => Quick and flicker free
Scenario 1b, 2b, 3b: UseItemStyleForSubItems = False
The ListView and its content is drawn by .NET (inside the framework)
..NET uses GDI+ => Slow and with flicker
Unfortunately you'll have to live with the flicker until the next version of
GDI+ is released. It is supposed to have support for hardware acceleration,
but AFAIK no official release date has been announced
/claes
mhetherington said:
Claes,
Thanks for the explanation, but I don't see how it fits in this case. Let
me add more detail and perhaps you or someone else can connect the dots for
me (everything below assumes VB.Net).
Initial Setup: Drop a ListView onto a Windows Form. Change the View
Property to Details. Set the GridLines Property to False. Add a handful of
Columns to the ListView (the more you add, the more obvious the flicker will
be, but it should be pretty obvious with as few as 5 Columns). Now, try
adding and manipulating ListViewItems and ListViewSubItems in the following
ways:
Scenario #1a: Populate the ListView with a couple ListViewItems to start
with. Set a Timer to change the Text Property of a few ListViewSubItems
every 5 seconds or so (perform an incremental count , or something, and
update the items to something obviously different). You should notice
almost no flicker (maybe once in every 10+ timer events).
Scenario #2a: Do the same as in Scenario #1a, but wrap your 5-sec changes
in a BeginUpdate/EndUpdate block. Flicker should be on par with that of
Scenario #1a (i.e., it doesn't seem to help, but it also doesn't seem to
hurt).
Scenario #3a: Do the same as Scenario #2a, but don't actually modify any
subitems on your 5-sec timer events. In other words, issue a BeginUpdate
followed immediately by an EndUpdate (without doing anything in-between).
You should see absolutely no flicker whatsoever (expected, right?...Wait
until Scenario #3b).
Scenario #1b: Same as Scenario #1a, but set the UseItemStyleForSubItems =
False on each ListViewItem you add to the ListView. You should observe
flicker on all but a (maybe) few passes of the 5-second timer event - there
should certainly be more flicker than any of the 3 previous scenarios).
Scenario #2b: Same as Scenario #1b, but wrap your 5-sec changes in a
BeginUpdate/EndUpdate block. Again, flicker occurs on nearly every pass of
the timer event.
Scenario #3b: Same as Scenario #2b, but don't actually modify any
subitems on your 5-sec timer events. In other words, issue a BeginUpdate
followed immediately by an EndUpdate (without doing anything in-between).
Unexpectedly, you'll note flicker on nearly every pass of the timer. But
why?!?!? Nothing has changed in the ListView - no text, no styles, no
nothing! I would have expected the results to be similar to those in
Scenario #3a.
So, while your point about differences in GDI+ not supporting hardware
acceleration may be entirely accurate, I'm still left wondering why GDI+ has
anything to do with explaining this particular phenomenon (i.e., the
difference in behavior between Scenarios #3a and #3b). No messages to
repaint/redraw should be sent whatsoever to the graphics subsystem, because
nothing has changed.
In my mind (without knowing any of the gory details of GDI+), the problem
seems to lie more in the design of the .Net ListView control. Specifically,
that it is designed "well enough" NOT to send any redraw/repaint messages
with UseItemStyleForSubItems = True (the default) when no changes are made
to the ListView. But, it's as if the control is sending repaint/redraw
messages each and every time EndUpdate is called with
UseItemStyleForSubItems = True, whether items/subitems have actually changed
or not (i.e., poor design of the control).
If this is not the case, can you or anyone explain this in a way to
clearly pinpoint GDI+ as the problem and not the control itself? In other
words, isn't it still up to the control itself to issue the redraw/repaint
messages? Thanks.