views:

69

answers:

6

I've tried overriding the OnLoad event, but the form is getting drawn before this method finishes. I am calling the base.OnLoad method. But, the form is partially getting drawn (artifacts are seen) during the event. I notice this because I'm hitting the database and it is taking some time. In the event, I'm getting some data and binding it to the form's controls. Please don't tell me to use a separate thread. For simplicity, I would rather just show a busy cursor while the data is being loaded.

UPDATE:

Ok, I think you guys/gals have convinced me. I'll use a separate thread. I wasn't aware of the BackgroundWorker and it was very easy to implement. Now my form is loading quickly. And then, all of a sudden my combo boxes are populated. But, I'd like prevent the user from clicking on the combos before they're populated. What is the best way/standard way of doing this using Winforms? Is there a way to turn off input events in the form until the background worker is finished?

+2  A: 

I would recommend that you cover the form with a Loading label before you start loading.

SLaks
A: 

I am not sure if this will help or not, but the Move event is called before Load.

RedFilter
+1  A: 

You could try doing your expensive operations in the form's constructor, so that when it's time to show the form, it already has the data it needs to render. Also look into SuspendLayout/ResumeLayout methods.

But none of these solutions will be as graceful as using a different thread to perform expensive operations.

Anna Lear
I've decided to use a BackgroundWorker to do the database hits. But, I'd still like to prevent the user from modifying data on the form until the worker is finished. How do I go about this? See my updated question for more details. Thanks.
bsh152s
I would start with your controls in a disabled state (i.e. Enabled = false). And enable them once the background operation finishes.
Anna Lear
+2  A: 

You should be able to solve the problem by placing your loading in the constructor code before the call to IntializeComponent(). At this point, the controls on the form have not yet been created (because this is what InitializeComponent does).

However, the form is also not yet visible in this phase. If you want to show a blank form, then I think a possible solution (I haven't tried that, but I think it should work) would be to call this.Show() (to display the form) and Application.DoEvents() to let WinForms process events and display the form.

Tomas Petricek
I agree that this is the simplest approach. However, the way we have things working is that our components go through a "class factory". Our app changes based on what components are installed and the way we figure out it is installed is by calling the constructor. Just trying to work with what I have.
bsh152s
A: 

The Shown event is good for this. Your form will be completely displayed, then the Shown event is fired. This will give the user a clean screen without partially drawn fields while you load your data.

In your Shown event handler, turn on the hourglass, do your work and then turn off the hourglass.

Brad Bruce
A: 

The ComboBox has a BeginUpdate() and EndUpdate() that can be called when adding large amounts of data or slow data to the control. SuspendLayout() and 'ResumeLayout()` on the form may also help with your redraw issues.

You can also disable the control, if all you want is to prevent the user from clicking it. If you disable the form itself, all contained controls will also be disabled.

If you're using background threads, you'll have to make sure you call these from the main UI thread before starting the thread, and again from the main UI thread when the background worker is complete.

James B