Формы C # - диалоговая форма только частично исчезает перед выполнением следующего действия - PullRequest
1 голос
/ 21 июля 2009

Я пытался найти это, но я не знал, как это описать. Если это дубликат, укажите мне на другой вопрос. Спасибо.

Я создал приложение C # Windows Forms, используя VS 2008. В основной форме он открывает настраиваемую диалоговую форму. Когда пользователь закрывает диалоговую форму, она полностью не исчезает, прежде чем приложение запускается в следующую задачу. Схема различных частей формы сохраняется до тех пор, пока не будут выполнены некоторые дополнительные задачи.

Это выглядит очень непрофессионально, и приложение кажется сломанным, хотя все работает отлично. Есть ли способ избежать и / или исправить эту проблему?

К вашему сведению, дополнительные задачи - это расчеты, запрошенные после закрытия формы.

Вот код закрытия формы.

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();
}

Вот код из главной формы, который открывает пользовательское модальное диалоговое окно и затем удаляет его после его закрытия. Я думаю, что dispose может быть избыточным, так как форма сама вызывает метод close.

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();

Затем устанавливается соединение с SQL Server для выполнения некоторых расчетов отчета.

Ответы [ 3 ]

2 голосов
/ 21 июля 2009

Я подозреваю, что последний бит является самым важным:

Затем устанавливается соединение с SQL Server для выполнения некоторых расчетов отчета.

Это все еще в потоке пользовательского интерфейса? Если это так, то это, вероятно, проблема - событие перерисовки для главного окна, вероятно, все еще ожидает, но вы заняты базой данных.

Предложение Фредрика о вызове Refresh является хорошим, но у вас все еще есть проблема слишком большого объема работы в потоке пользовательского интерфейса. Если по какой-либо причине установление соединения с SQL Server займет много времени, ваш пользовательский интерфейс будет заморожен в течение этого времени - вы не сможете его переместить, изменить его размер и т. Д.

Длительные операции - включая практически все, что связано с базой данных - в идеале должны выполняться в другом потоке. Это, несомненно, усложняет ситуацию, но в итоге дает гораздо лучший интерфейс.

1 голос
/ 21 июля 2009

Что вы можете сделать, это заставить вызывающую форму перекраситься после закрытия диалога, прежде чем продолжить работу с другими вещами:

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();

Обратите внимание, что есть два метода, которые заставят форму (или элемент управления) перерисовывать себя: Invalidate и Refresh. Refresh немедленно вызовет полную перерисовку. Invalidate не приведет к немедленной перерисовке, но сделает недействительной полную поверхность элемента управления, так что полная поверхность будет перекрашена при следующем обновлении элемента управления (что может быть немного задержано, если поток занят другими вещами, как ваш случай).

Чтобы вызвать перерисовку после вызова Invalidate, вы можете вызвать метод Update, который вызовет немедленную перерисовку недействительных областей. Так что, в вашем случае, вы могли бы просто позвонить Update вместо Refresh, так как я предполагаю, что области, которые были ранее покрыты диалогом, должны быть признаны недействительными. Это может быть более эффективным, чем принудительное перекрашивание:

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();
0 голосов
/ 21 июля 2009

Похоже, ваша основная форма не обновляется. Вы можете попробовать вызвать this.Refresh () после showdialog?

...