JK.
JK.

Reputation: 1154

C# Forms - dialog form only partially disappears before next action taken

I tried to search for this, but I was not sure how to describe it. If it is a duplicate, please point me to the other question. Thanks.

I created a C# Windows Forms app using VS 2008. From the main form it opens a custom dialog form. When the user closes the dialog form, it does not completely disappear before the application starts into it's next task. The outline of various parts of the form remains until some additional tasks are completed.

This looks very unprofessional and it makes the application appear to be broken, even though everything works great. Is there any way to avoid and/or fix this problem?

FYI, the additional tasks are calculations requested after the form has been closed.

Here is the form closing code.

private void CloseForm_Click(object sender, EventArgs e)
{
    Properties.Settings.Default.EndDate = cmbBoxRptDate.SelectedValue.ToString();
    rptDate = cmbBoxRptDate.SelectedValue.ToString();
    Var1 = cmbBoxVar1.SelectedValue.ToString();
    Var2 = cmbBoxVar2.SelectedValue.ToString();
    this.Close();
}

Here is the code from the main form that opens the custom modal dialog and then disposes of it after it is closed. I think the dispose might be redundant since the form calls the close method on it's own.

RptSettingsForm RS = new RptSettingsForm();
DialogResult DR = RS.ShowDialog();
String var1 = RS.getVar1().ToString();
String var2 = RS.getVar2().ToString();
String rptDate = RS.getDate().ToString();
RS.Dispose();

Then a connection is established to SQL Server to do some report calculations.

Upvotes: 1

Views: 1801

Answers (3)

Fredrik Mörk
Fredrik Mörk

Reputation: 158379

What you can do is to force the calling form to repaint itself after the dialog is closed, before carrying on with other stuff:

RptSettingsForm RS = new RptSettingsForm();
DialogResult DR = RS.ShowDialog();
this.Refresh(); // force repaint
String var1 = RS.getVar1().ToString();
String var2 = RS.getVar2().ToString();
String rptDate = RS.getDate().ToString();
RS.Dispose();

Note that there are two methods that will cause a form (or control) to repaint itself: Invalidate and Refresh. Refresh will force a full repaint immediately. Invalidate will not cause an immediate repaint, but rather invalidate the full control surface so that the full surface will be repainted the next time the control is updated (which may be delayed a bit if the thread is busy with other stuff, as in your case).

To force a repaint after calling Invalidate, you can call the Update method, which will force an immediate repaint of invalidated areas. So it may be, in your case, that you could simply call Update instead of Refresh, since I guess that the areas that were previously covered by the dialog should be invalidated. This might be more efficient that forcing a full repaint:

RptSettingsForm RS = new RptSettingsForm();
DialogResult DR = RS.ShowDialog();
this.Update(); // force repaint of invalidated areas
String var1 = RS.getVar1().ToString();
String var2 = RS.getVar2().ToString();
String rptDate = RS.getDate().ToString();
RS.Dispose();

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1503280

I suspect the last bit is the most important:

Then a connection is established to SQL Server to do some report calculations.

Is that still on the UI thread? If so, that's probably the problem - the repaint event for the main window is probably still waiting to happen, but you're busy with the database.

Fredrik's suggestion of calling Refresh is a good one, but you've still fundamentally got the problem of doing too much on the UI thread. If for whatever reason it takes a long time to establish a connection to SQL Server, your UI will be frozen during that time - you won't be able to move it, resize it etc.

Long-running operations - including just about anything to do with a database - should ideally be done on a different thread. This does make things trickier, without a doubt, but gives a much better UI in the end.

Upvotes: 2

chikak
chikak

Reputation: 1732

Looks like your main form is not getting refreshed. can you try calling this.Refresh() after showdialog?

Upvotes: 0

Related Questions