By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,492 Members | 1,242 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,492 IT Pros & Developers. It's quick & easy.

Weird GUI performance slowdown

P: n/a
Hi,

On a simple form, I have a ListBox control. This listbox control is loaded
with around 800 text items of somewhat short length. There are also some
other controls on the form, buttons. When the form need to repaint itself
after e.g. maximize, it happens somewhat slow, I can see the buttons redrawn
one by one. I realy do not understand why. If I load twice the amount of text
into the list control, the form repaint itself twice as slow. Memorywise it
should a piece of cake - my computer is running xp on a 1gb core 2 duo box.
All other programs I develop and that has a far bigger memory footprint runs
without any delay at all. The list control is onlys showing some 30 top text
items. Anything to do about this. The listbox is embedded in a
splitcontainer. Is the listbox repainted (re-layed out) for every paint event
for other controls on a form????

Any ideas?
Sep 28 '07 #1
Share this Question
Share on Google+
4 Replies


P: n/a
On a simple form, I have a ListBox control. This listbox control is loaded
with around 800 text items of somewhat short length. There are also some
other controls on the form, buttons. When the form need to repaint itself
after e.g. maximize, it happens somewhat slow, I can see the buttons redrawn
one by one.
It probably has to do with the amount of controls on your form. This
text that I copied from the Microsoft MSDN Forums might be useful to you
(author: Hans Passant, nobugz)


A frequently heard complaint at this forum is Windows Forms' tendency to
cause "flicker" on forms with a lot of controls. There are two causes
for this kind of flicker:

1. Windows sends a control two messages when a control needs to be
painted. The first one (WM_ERASEBKGND) causes the background to be
painted (OnPaintBackground), the second causes the foreground to be
painted (WM_PAINT, firing OnPaint). Seeing the background drawn first,
then the foreground is noticeable when the drawing is slow. Windows
Forms has a ready solution for this kind of flicker with
ControlStyles.OptimizedDoubleBuffer.

2. A form that has a lot of controls takes a long time to paint.
Especially the Button control in its default style is expensive. Once
you get over 50 controls, it starts getting noticeable. The Form class
paints its background first and leaves "holes" where the controls need
to go. Those holes are usually white, black when you use the Opacity or
TransparencyKey property. Then each control gets painted, filling in
the holes. The visual effect is ugly and there's no ready solution for
it in Windows Forms. Double-buffering can't solve it as it only works
for a single control, not a composite set of controls.

I discovered a new Windows style in the SDK header files, available for
Windows XP and (presumably) Vista: WS_EX_COMPOSITED. With that style
turned on for your form, Windows XP does double-buffering on the form
and all its child controls. This effectively solves the 2nd cause of
flicker. Here's an example:

using System;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsApplication1 {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
for (int ix = 0; ix < 30; ++ix) {
for (int iy = 0; iy < 30; ++iy) {
Button btn = new Button();
btn.Location = new Point(ix*10, iy*10);
this.Controls.Add(btn);
}
}
}
protected override CreateParams CreateParams {
get {
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
}
}

To see it at work, minimize and restore the form and observe its
painting behavior. Comment the cp.ExStyle assignment to see the
difference. All you have to do to use this in your own form is to copy
and paste the CreateParams property.

Some caveats with this: this doesn't speed up the painting. Your form
just stays invisible while painting is taking place, then pops on the
screen when it is done. And it doesn't work when you use the Opacity or
TransparencyKey property, the form outline will be visible as an ugly
black rectangle while painting takes place. The best solution for that
is to use a timer to increment the Opacity value to 99% to make the form
visible after it is painted.

I haven't experimented a great deal with this as yet, please post to
this thread if you have problems using it.
Hans Passant. 9/20:
Sep 28 '07 #2

P: n/a
Mulder, Thanks for your reply. However, there aren't many controls on my
form, and the 'flicker' is caused by the amount of text in the listBox. If
there are only 100 items no flicker occur, however, with increasing number of
lines in the listBox, flicker starts and get worse.

"Martijn Mulder" wrote:
On a simple form, I have a ListBox control. This listbox control is loaded
with around 800 text items of somewhat short length. There are also some
other controls on the form, buttons. When the form need to repaint itself
after e.g. maximize, it happens somewhat slow, I can see the buttons redrawn
one by one.

It probably has to do with the amount of controls on your form. This
text that I copied from the Microsoft MSDN Forums might be useful to you
(author: Hans Passant, nobugz)


A frequently heard complaint at this forum is Windows Forms' tendency to
cause "flicker" on forms with a lot of controls. There are two causes
for this kind of flicker:

1. Windows sends a control two messages when a control needs to be
painted. The first one (WM_ERASEBKGND) causes the background to be
painted (OnPaintBackground), the second causes the foreground to be
painted (WM_PAINT, firing OnPaint). Seeing the background drawn first,
then the foreground is noticeable when the drawing is slow. Windows
Forms has a ready solution for this kind of flicker with
ControlStyles.OptimizedDoubleBuffer.

2. A form that has a lot of controls takes a long time to paint.
Especially the Button control in its default style is expensive. Once
you get over 50 controls, it starts getting noticeable. The Form class
paints its background first and leaves "holes" where the controls need
to go. Those holes are usually white, black when you use the Opacity or
TransparencyKey property. Then each control gets painted, filling in
the holes. The visual effect is ugly and there's no ready solution for
it in Windows Forms. Double-buffering can't solve it as it only works
for a single control, not a composite set of controls.

I discovered a new Windows style in the SDK header files, available for
Windows XP and (presumably) Vista: WS_EX_COMPOSITED. With that style
turned on for your form, Windows XP does double-buffering on the form
and all its child controls. This effectively solves the 2nd cause of
flicker. Here's an example:

using System;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsApplication1 {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
for (int ix = 0; ix < 30; ++ix) {
for (int iy = 0; iy < 30; ++iy) {
Button btn = new Button();
btn.Location = new Point(ix*10, iy*10);
this.Controls.Add(btn);
}
}
}
protected override CreateParams CreateParams {
get {
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
}
}

To see it at work, minimize and restore the form and observe its
painting behavior. Comment the cp.ExStyle assignment to see the
difference. All you have to do to use this in your own form is to copy
and paste the CreateParams property.

Some caveats with this: this doesn't speed up the painting. Your form
just stays invisible while painting is taking place, then pops on the
screen when it is done. And it doesn't work when you use the Opacity or
TransparencyKey property, the form outline will be visible as an ugly
black rectangle while painting takes place. The best solution for that
is to use a timer to increment the Opacity value to 99% to make the form
visible after it is painted.

I haven't experimented a great deal with this as yet, please post to
this thread if you have problems using it.
Hans Passant. 9/20:
Sep 29 '07 #3

P: n/a
Jesper, Denmark wrote:
Hi,

On a simple form, I have a ListBox control. This listbox control is
loaded with around 800 text items of somewhat short length. There are
also some other controls on the form, buttons. When the form need to
repaint itself after e.g. maximize, it happens somewhat slow, I can
see the buttons redrawn one by one. I realy do not understand why. If
I load twice the amount of text into the list control, the form
repaint itself twice as slow. Memorywise it should a piece of cake -
my computer is running xp on a 1gb core 2 duo box. All other
programs I develop and that has a far bigger memory footprint runs
without any delay at all. The list control is onlys showing some 30
top text items. Anything to do about this. The listbox is embedded in
a splitcontainer. Is the listbox repainted (re-layed out) for every
paint event for other controls on a form????
Probably. Winforms is pretty crappy written, mind you. It's a
synchronous API on top of asynchronous Win32 message based code.

What you could try is instead of the split container, you could use a
panel and in there you place the listcontrol and a splitter bar.

FB

--
------------------------------------------------------------------------
Lead developer of LLBLGen Pro, the productive O/R mapper for .NET
LLBLGen Pro website: http://www.llblgen.com
My .NET blog: http://weblogs.asp.net/fbouma
Microsoft MVP (C#)
------------------------------------------------------------------------
Sep 30 '07 #4

P: n/a
By using the above method it feels that flickering is removed but my program crashes on linked label.
Oct 7 '08 #5

This discussion thread is closed

Replies have been disabled for this discussion.