Windows forms slow drawing of controls

G

Guest

When I show a form composed of some 20 controls, including one complicated
control, it takes about 2 seconds from the moment of form.show() to the point
where everything is drawn. What can I do so that this doesn't happen, or
that I at least hide it from the users ? I've tried double buffering but
this doesn't seem to work. (There is also no code in the form except for the
constructor of the form.)

What I've also found is, when I call form.show and then follow by a
Thread.Sleep, it will draw a couple of controls and then wait for the
Thread.Sleep to draw the rest of the controls. (see code below) What's going
on here ?

Main frmMain = new Main(1, 1);
frmMain.Show();
Thread.Sleep(10000);
 
K

Kevin Spencer

What's going on is, you're putting the main execution thread to sleep, thus
delaying any execution of code for 10 seconds. A Windows Form is a STA
(Single Threaded Apartment) application. There is only one execution thread.

Call SuspendLayout() on the Form while loading the Controls. When they are
loaded, call ResumeLayout(). This prevents the Form from repainting until
all of the Controls are loaded.

--
HTH,

Kevin Spencer
Microsoft MVP
Software Composer
http://unclechutney.blogspot.com

A man, a plan, a canal, a palindrome that has.. oh, never mind.
 
G

Guest

Hi Kevin,

I'm still not getting there. Putting in SuspendLayout/ResumeLayout doesn't
change anything. Am I doing something wrong ? I tried putting it in
different places (see code below)

Main frmMain = new Main(1, 1);
frmMain.SuspendLayout();
frmMain.Show();
frmMain.ResumeLayout();

-or-

public Main(int gebruiker, int rol)
{
SuspendLayout();

InitializeComponent();

this.gebruiker = gebruiker;
this.rol = rol;

splitContainer2.Panel2.Controls.Clear();
Vondeling fr = new Vondeling();
splitContainer2.Panel2.Controls.Add(fr);
splitContainer2.Panel2.Controls[0].Dock = DockStyle.Fill;

ResumeLayout();
}

As for threading : the fact that it's single threaded is the part that I
don't get. If it's single treaded, shouldn't the form be drawn completely
before the code gets to the sleeping part ?
 
K

Kevin Spencer

I don't know the context of your code, or what you expect in terms of
behavior. You seem to instantiating a form with a class name Main somewhere
in your code, but I can't tell where (is this the main Form of the app?).
Calling SuspendLayout will not speed up the initialization of any Controls,
but prevents Layout logic from being executed during their initialization.
In addition, the InitializeComponent method of the Form calls SuspendLayout,
ResumeLayout, and PerformLayout on the Form. You're calling SuspendLayout on
the Form prior to calling InitializeComponent, and ResumeLayout after.
SuspendLayout can be called multiple times in succession, but if the count
of SuspendLayout calls is greater than 0, ResumeLayout will not execute
properly (resuming layout). Also, the PerformLayout call will not raise a
Layout event. So, I'm not at all sure how your code would play out.

See
http://msdn2.microsoft.com/en-us/library/system.windows.forms.control.suspendlayout.aspx
for further details.

--
HTH,

Kevin Spencer
Microsoft MVP
Computer Control Freak
http://unclechutney.blogspot.com

A man, a plan, a canal, a palindrome that has.. oh, never mind.

Chaos said:
Hi Kevin,

I'm still not getting there. Putting in SuspendLayout/ResumeLayout
doesn't
change anything. Am I doing something wrong ? I tried putting it in
different places (see code below)

Main frmMain = new Main(1, 1);
frmMain.SuspendLayout();
frmMain.Show();
frmMain.ResumeLayout();

-or-

public Main(int gebruiker, int rol)
{
SuspendLayout();

InitializeComponent();

this.gebruiker = gebruiker;
this.rol = rol;

splitContainer2.Panel2.Controls.Clear();
Vondeling fr = new Vondeling();
splitContainer2.Panel2.Controls.Add(fr);
splitContainer2.Panel2.Controls[0].Dock = DockStyle.Fill;

ResumeLayout();
}

As for threading : the fact that it's single threaded is the part that I
don't get. If it's single treaded, shouldn't the form be drawn completely
before the code gets to the sleeping part ?

Kevin Spencer said:
What's going on is, you're putting the main execution thread to sleep,
thus
delaying any execution of code for 10 seconds. A Windows Form is a STA
(Single Threaded Apartment) application. There is only one execution
thread.

Call SuspendLayout() on the Form while loading the Controls. When they
are
loaded, call ResumeLayout(). This prevents the Form from repainting until
all of the Controls are loaded.

--
HTH,

Kevin Spencer
Microsoft MVP
Software Composer
http://unclechutney.blogspot.com

A man, a plan, a canal, a palindrome that has.. oh, never mind.
 
G

Guest

Kevin,

The application starts with a login form. If the login is correct I want
the user to see the Main form, which is the code snippet I provided. Now,
I've taken a screenshot to give you an idea of what I'm happens...

http://www.flickr.com/photos/21415710@N00/263834581/

This happens using the standard code (so before adding double buffer stuff,
resumelayout and such).

The app starts like that and taken about 1-2 seconds before it becomes fully
drawn. What I want now, is basically that when the form shows, everything is
already drawn. So I want to move those 1-2 seconds to the background, so
that the user doesn't see the form being drawn.

This kind of behaviour is also the thing I get when I put in that
Thread.Sleep part. It draws something like you see in the screenshot, then
sleeps for 10 seconds and then draws the rest of the form.

Kevin Spencer said:
I don't know the context of your code, or what you expect in terms of
behavior. You seem to instantiating a form with a class name Main somewhere
in your code, but I can't tell where (is this the main Form of the app?).
Calling SuspendLayout will not speed up the initialization of any Controls,
but prevents Layout logic from being executed during their initialization.
In addition, the InitializeComponent method of the Form calls SuspendLayout,
ResumeLayout, and PerformLayout on the Form. You're calling SuspendLayout on
the Form prior to calling InitializeComponent, and ResumeLayout after.
SuspendLayout can be called multiple times in succession, but if the count
of SuspendLayout calls is greater than 0, ResumeLayout will not execute
properly (resuming layout). Also, the PerformLayout call will not raise a
Layout event. So, I'm not at all sure how your code would play out.

See
http://msdn2.microsoft.com/en-us/library/system.windows.forms.control.suspendlayout.aspx
for further details.

--
HTH,

Kevin Spencer
Microsoft MVP
Computer Control Freak
http://unclechutney.blogspot.com

A man, a plan, a canal, a palindrome that has.. oh, never mind.

Chaos said:
Hi Kevin,

I'm still not getting there. Putting in SuspendLayout/ResumeLayout
doesn't
change anything. Am I doing something wrong ? I tried putting it in
different places (see code below)

Main frmMain = new Main(1, 1);
frmMain.SuspendLayout();
frmMain.Show();
frmMain.ResumeLayout();

-or-

public Main(int gebruiker, int rol)
{
SuspendLayout();

InitializeComponent();

this.gebruiker = gebruiker;
this.rol = rol;

splitContainer2.Panel2.Controls.Clear();
Vondeling fr = new Vondeling();
splitContainer2.Panel2.Controls.Add(fr);
splitContainer2.Panel2.Controls[0].Dock = DockStyle.Fill;

ResumeLayout();
}

As for threading : the fact that it's single threaded is the part that I
don't get. If it's single treaded, shouldn't the form be drawn completely
before the code gets to the sleeping part ?

Kevin Spencer said:
What's going on is, you're putting the main execution thread to sleep,
thus
delaying any execution of code for 10 seconds. A Windows Form is a STA
(Single Threaded Apartment) application. There is only one execution
thread.

Call SuspendLayout() on the Form while loading the Controls. When they
are
loaded, call ResumeLayout(). This prevents the Form from repainting until
all of the Controls are loaded.

--
HTH,

Kevin Spencer
Microsoft MVP
Software Composer
http://unclechutney.blogspot.com

A man, a plan, a canal, a palindrome that has.. oh, never mind.

When I show a form composed of some 20 controls, including one
complicated
control, it takes about 2 seconds from the moment of form.show() to the
point
where everything is drawn. What can I do so that this doesn't happen,
or
that I at least hide it from the users ? I've tried double buffering
but
this doesn't seem to work. (There is also no code in the form except
for
the
constructor of the form.)

What I've also found is, when I call form.show and then follow by a
Thread.Sleep, it will draw a couple of controls and then wait for the
Thread.Sleep to draw the rest of the controls. (see code below) What's
going
on here ?

Main frmMain = new Main(1, 1);
frmMain.Show();
Thread.Sleep(10000);
 
K

Kevin Spencer

Here's your best bet, when you want to start out with a Login Form: Create
the main Form as the main application Form (as you normally would), and add
your Login Form to it as a member field. In the (main) Form's consturctor,
create an instance of the login Form. In the OnLoad method of the (main)
Form, call the ShowDialog method on it. When the login Form closes, the main
form will show. No need for any complexity.

--
HTH,

Kevin Spencer
Microsoft MVP
Computer Control Freak
http://unclechutney.blogspot.com

A man, a plan, a canal, a palindrome that has.. oh, never mind.

Chaos said:
Kevin,

The application starts with a login form. If the login is correct I want
the user to see the Main form, which is the code snippet I provided. Now,
I've taken a screenshot to give you an idea of what I'm happens...

http://www.flickr.com/photos/21415710@N00/263834581/

This happens using the standard code (so before adding double buffer
stuff,
resumelayout and such).

The app starts like that and taken about 1-2 seconds before it becomes
fully
drawn. What I want now, is basically that when the form shows, everything
is
already drawn. So I want to move those 1-2 seconds to the background, so
that the user doesn't see the form being drawn.

This kind of behaviour is also the thing I get when I put in that
Thread.Sleep part. It draws something like you see in the screenshot,
then
sleeps for 10 seconds and then draws the rest of the form.

Kevin Spencer said:
I don't know the context of your code, or what you expect in terms of
behavior. You seem to instantiating a form with a class name Main
somewhere
in your code, but I can't tell where (is this the main Form of the app?).
Calling SuspendLayout will not speed up the initialization of any
Controls,
but prevents Layout logic from being executed during their
initialization.
In addition, the InitializeComponent method of the Form calls
SuspendLayout,
ResumeLayout, and PerformLayout on the Form. You're calling SuspendLayout
on
the Form prior to calling InitializeComponent, and ResumeLayout after.
SuspendLayout can be called multiple times in succession, but if the
count
of SuspendLayout calls is greater than 0, ResumeLayout will not execute
properly (resuming layout). Also, the PerformLayout call will not raise a
Layout event. So, I'm not at all sure how your code would play out.

See
http://msdn2.microsoft.com/en-us/library/system.windows.forms.control.suspendlayout.aspx
for further details.

--
HTH,

Kevin Spencer
Microsoft MVP
Computer Control Freak
http://unclechutney.blogspot.com

A man, a plan, a canal, a palindrome that has.. oh, never mind.

Chaos said:
Hi Kevin,

I'm still not getting there. Putting in SuspendLayout/ResumeLayout
doesn't
change anything. Am I doing something wrong ? I tried putting it in
different places (see code below)

Main frmMain = new Main(1, 1);
frmMain.SuspendLayout();
frmMain.Show();
frmMain.ResumeLayout();

-or-

public Main(int gebruiker, int rol)
{
SuspendLayout();

InitializeComponent();

this.gebruiker = gebruiker;
this.rol = rol;

splitContainer2.Panel2.Controls.Clear();
Vondeling fr = new Vondeling();
splitContainer2.Panel2.Controls.Add(fr);
splitContainer2.Panel2.Controls[0].Dock = DockStyle.Fill;

ResumeLayout();
}

As for threading : the fact that it's single threaded is the part that
I
don't get. If it's single treaded, shouldn't the form be drawn
completely
before the code gets to the sleeping part ?

:

What's going on is, you're putting the main execution thread to sleep,
thus
delaying any execution of code for 10 seconds. A Windows Form is a STA
(Single Threaded Apartment) application. There is only one execution
thread.

Call SuspendLayout() on the Form while loading the Controls. When they
are
loaded, call ResumeLayout(). This prevents the Form from repainting
until
all of the Controls are loaded.

--
HTH,

Kevin Spencer
Microsoft MVP
Software Composer
http://unclechutney.blogspot.com

A man, a plan, a canal, a palindrome that has.. oh, never mind.

When I show a form composed of some 20 controls, including one
complicated
control, it takes about 2 seconds from the moment of form.show() to
the
point
where everything is drawn. What can I do so that this doesn't
happen,
or
that I at least hide it from the users ? I've tried double
buffering
but
this doesn't seem to work. (There is also no code in the form
except
for
the
constructor of the form.)

What I've also found is, when I call form.show and then follow by a
Thread.Sleep, it will draw a couple of controls and then wait for
the
Thread.Sleep to draw the rest of the controls. (see code below)
What's
going
on here ?

Main frmMain = new Main(1, 1);
frmMain.Show();
Thread.Sleep(10000);
 
G

Guest

Kevin, the problem is that this isn't even specific to my application. If I
simply create a new project and put some 20 controls on the form, I'll
already get a 0.5 second delay. When I then put on the navbarcontrol from
devexpress, It jumps to 2 seconds. The point is, I don't even want to see
that 0.5 second delay with the standard windows forms controls. To
reiterate, the problem isn't the delay as such, it's the fact that you can
see the controls being drawn. I'd rather put the user on a waitcursor for 2
seconds instead of them seeing a form being drawn.

Should I start believing that this is simply a limitation of .net ?

Kevin Spencer said:
Here's your best bet, when you want to start out with a Login Form: Create
the main Form as the main application Form (as you normally would), and add
your Login Form to it as a member field. In the (main) Form's consturctor,
create an instance of the login Form. In the OnLoad method of the (main)
Form, call the ShowDialog method on it. When the login Form closes, the main
form will show. No need for any complexity.

--
HTH,

Kevin Spencer
Microsoft MVP
Computer Control Freak
http://unclechutney.blogspot.com

A man, a plan, a canal, a palindrome that has.. oh, never mind.

Chaos said:
Kevin,

The application starts with a login form. If the login is correct I want
the user to see the Main form, which is the code snippet I provided. Now,
I've taken a screenshot to give you an idea of what I'm happens...

http://www.flickr.com/photos/21415710@N00/263834581/

This happens using the standard code (so before adding double buffer
stuff,
resumelayout and such).

The app starts like that and taken about 1-2 seconds before it becomes
fully
drawn. What I want now, is basically that when the form shows, everything
is
already drawn. So I want to move those 1-2 seconds to the background, so
that the user doesn't see the form being drawn.

This kind of behaviour is also the thing I get when I put in that
Thread.Sleep part. It draws something like you see in the screenshot,
then
sleeps for 10 seconds and then draws the rest of the form.

Kevin Spencer said:
I don't know the context of your code, or what you expect in terms of
behavior. You seem to instantiating a form with a class name Main
somewhere
in your code, but I can't tell where (is this the main Form of the app?).
Calling SuspendLayout will not speed up the initialization of any
Controls,
but prevents Layout logic from being executed during their
initialization.
In addition, the InitializeComponent method of the Form calls
SuspendLayout,
ResumeLayout, and PerformLayout on the Form. You're calling SuspendLayout
on
the Form prior to calling InitializeComponent, and ResumeLayout after.
SuspendLayout can be called multiple times in succession, but if the
count
of SuspendLayout calls is greater than 0, ResumeLayout will not execute
properly (resuming layout). Also, the PerformLayout call will not raise a
Layout event. So, I'm not at all sure how your code would play out.

See
http://msdn2.microsoft.com/en-us/library/system.windows.forms.control.suspendlayout.aspx
for further details.

--
HTH,

Kevin Spencer
Microsoft MVP
Computer Control Freak
http://unclechutney.blogspot.com

A man, a plan, a canal, a palindrome that has.. oh, never mind.

Hi Kevin,

I'm still not getting there. Putting in SuspendLayout/ResumeLayout
doesn't
change anything. Am I doing something wrong ? I tried putting it in
different places (see code below)

Main frmMain = new Main(1, 1);
frmMain.SuspendLayout();
frmMain.Show();
frmMain.ResumeLayout();

-or-

public Main(int gebruiker, int rol)
{
SuspendLayout();

InitializeComponent();

this.gebruiker = gebruiker;
this.rol = rol;

splitContainer2.Panel2.Controls.Clear();
Vondeling fr = new Vondeling();
splitContainer2.Panel2.Controls.Add(fr);
splitContainer2.Panel2.Controls[0].Dock = DockStyle.Fill;

ResumeLayout();
}

As for threading : the fact that it's single threaded is the part that
I
don't get. If it's single treaded, shouldn't the form be drawn
completely
before the code gets to the sleeping part ?

:

What's going on is, you're putting the main execution thread to sleep,
thus
delaying any execution of code for 10 seconds. A Windows Form is a STA
(Single Threaded Apartment) application. There is only one execution
thread.

Call SuspendLayout() on the Form while loading the Controls. When they
are
loaded, call ResumeLayout(). This prevents the Form from repainting
until
all of the Controls are loaded.

--
HTH,

Kevin Spencer
Microsoft MVP
Software Composer
http://unclechutney.blogspot.com

A man, a plan, a canal, a palindrome that has.. oh, never mind.

When I show a form composed of some 20 controls, including one
complicated
control, it takes about 2 seconds from the moment of form.show() to
the
point
where everything is drawn. What can I do so that this doesn't
happen,
or
that I at least hide it from the users ? I've tried double
buffering
but
this doesn't seem to work. (There is also no code in the form
except
for
the
constructor of the form.)

What I've also found is, when I call form.show and then follow by a
Thread.Sleep, it will draw a couple of controls and then wait for
the
Thread.Sleep to draw the rest of the controls. (see code below)
What's
going
on here ?

Main frmMain = new Main(1, 1);
frmMain.Show();
Thread.Sleep(10000);
 
S

Stuart Nathan

You could try hiding the various toolbars etc and only show them once
everything is loaded.
 
K

Kevin Spencer

If you do what I told you, the form will not show until the dialog form
closes.

--
HTH,

Kevin Spencer
Microsoft MVP
Chicken Salad Shooter
http://unclechutney.blogspot.com

A man, a plan, a canal, a palindrome that has.. oh, never mind.

Chaos said:
Kevin, the problem is that this isn't even specific to my application. If
I
simply create a new project and put some 20 controls on the form, I'll
already get a 0.5 second delay. When I then put on the navbarcontrol from
devexpress, It jumps to 2 seconds. The point is, I don't even want to see
that 0.5 second delay with the standard windows forms controls. To
reiterate, the problem isn't the delay as such, it's the fact that you can
see the controls being drawn. I'd rather put the user on a waitcursor for
2
seconds instead of them seeing a form being drawn.

Should I start believing that this is simply a limitation of .net ?

Kevin Spencer said:
Here's your best bet, when you want to start out with a Login Form:
Create
the main Form as the main application Form (as you normally would), and
add
your Login Form to it as a member field. In the (main) Form's
consturctor,
create an instance of the login Form. In the OnLoad method of the (main)
Form, call the ShowDialog method on it. When the login Form closes, the
main
form will show. No need for any complexity.

--
HTH,

Kevin Spencer
Microsoft MVP
Computer Control Freak
http://unclechutney.blogspot.com

A man, a plan, a canal, a palindrome that has.. oh, never mind.

Chaos said:
Kevin,

The application starts with a login form. If the login is correct I
want
the user to see the Main form, which is the code snippet I provided.
Now,
I've taken a screenshot to give you an idea of what I'm happens...

http://www.flickr.com/photos/21415710@N00/263834581/

This happens using the standard code (so before adding double buffer
stuff,
resumelayout and such).

The app starts like that and taken about 1-2 seconds before it becomes
fully
drawn. What I want now, is basically that when the form shows,
everything
is
already drawn. So I want to move those 1-2 seconds to the background,
so
that the user doesn't see the form being drawn.

This kind of behaviour is also the thing I get when I put in that
Thread.Sleep part. It draws something like you see in the screenshot,
then
sleeps for 10 seconds and then draws the rest of the form.

:

I don't know the context of your code, or what you expect in terms of
behavior. You seem to instantiating a form with a class name Main
somewhere
in your code, but I can't tell where (is this the main Form of the
app?).
Calling SuspendLayout will not speed up the initialization of any
Controls,
but prevents Layout logic from being executed during their
initialization.
In addition, the InitializeComponent method of the Form calls
SuspendLayout,
ResumeLayout, and PerformLayout on the Form. You're calling
SuspendLayout
on
the Form prior to calling InitializeComponent, and ResumeLayout after.
SuspendLayout can be called multiple times in succession, but if the
count
of SuspendLayout calls is greater than 0, ResumeLayout will not
execute
properly (resuming layout). Also, the PerformLayout call will not
raise a
Layout event. So, I'm not at all sure how your code would play out.

See
http://msdn2.microsoft.com/en-us/library/system.windows.forms.control.suspendlayout.aspx
for further details.

--
HTH,

Kevin Spencer
Microsoft MVP
Computer Control Freak
http://unclechutney.blogspot.com

A man, a plan, a canal, a palindrome that has.. oh, never mind.

Hi Kevin,

I'm still not getting there. Putting in SuspendLayout/ResumeLayout
doesn't
change anything. Am I doing something wrong ? I tried putting it in
different places (see code below)

Main frmMain = new Main(1, 1);
frmMain.SuspendLayout();
frmMain.Show();
frmMain.ResumeLayout();

-or-

public Main(int gebruiker, int rol)
{
SuspendLayout();

InitializeComponent();

this.gebruiker = gebruiker;
this.rol = rol;

splitContainer2.Panel2.Controls.Clear();
Vondeling fr = new Vondeling();
splitContainer2.Panel2.Controls.Add(fr);
splitContainer2.Panel2.Controls[0].Dock = DockStyle.Fill;

ResumeLayout();
}

As for threading : the fact that it's single threaded is the part
that
I
don't get. If it's single treaded, shouldn't the form be drawn
completely
before the code gets to the sleeping part ?

:

What's going on is, you're putting the main execution thread to
sleep,
thus
delaying any execution of code for 10 seconds. A Windows Form is a
STA
(Single Threaded Apartment) application. There is only one
execution
thread.

Call SuspendLayout() on the Form while loading the Controls. When
they
are
loaded, call ResumeLayout(). This prevents the Form from repainting
until
all of the Controls are loaded.

--
HTH,

Kevin Spencer
Microsoft MVP
Software Composer
http://unclechutney.blogspot.com

A man, a plan, a canal, a palindrome that has.. oh, never mind.

When I show a form composed of some 20 controls, including one
complicated
control, it takes about 2 seconds from the moment of form.show()
to
the
point
where everything is drawn. What can I do so that this doesn't
happen,
or
that I at least hide it from the users ? I've tried double
buffering
but
this doesn't seem to work. (There is also no code in the form
except
for
the
constructor of the form.)

What I've also found is, when I call form.show and then follow by
a
Thread.Sleep, it will draw a couple of controls and then wait for
the
Thread.Sleep to draw the rest of the controls. (see code below)
What's
going
on here ?

Main frmMain = new Main(1, 1);
frmMain.Show();
Thread.Sleep(10000);
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top