2

我的表单上有一个按钮,单击它时会执行以下操作:

private void btnCheckSVN_Click(object sender, EventArgs e)
{
    wait = new DevExpress.Utils.WaitDialogForm("Fetching File SVN Status", 
                                               "Please Wait");
    wait.AutoSize = true;
    wait.Visible = false;
    bgwSVN.RunWorkerAsync();
    wait.ShowDialog();
}
private void bgwSVN_DoWork(object sender, DoWorkEventArgs e)
{
    e.Result = svn.SvnStatusEventArgsToDataTable(svn.CheckSVN(_localPath));
}

private void bgwSVn_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    DataTable dt = (DataTable)e.Result;
    dt.DefaultView.Sort = "File ASC";
    gdcSVN.DataSource = dt;
    gdcSVNDefaultView.BestFitColumns();
    xtcTabs.SelectedTabPageIndex = 1;
    lblTotalFileCount.Text = dt.Rows.Count.ToString();
    if (dt.Rows.Count == 0)
        XtraMessageBox.Show("No files found.", 
                            "Error",
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Error);
    wait.Close();
}

使用这种操作顺序,您(显然)仍然可以看到后面的等待对话框,MessageBox在我看来它看起来真的很草率。

如果我切换 IF 语句和Close()调用,我的WaitDialogForm一半会因为缺少更好的术语而消失。有一个带有红色框的空矩形和一个巨大的 X 穿过它,然后在它的MessageBox顶部作为它自己的形式。

这是我第一次搞乱任何类型的多线程或使用BackgroundWorker对象,所以我确定我只是错过了一些非常愚蠢的东西,但我不知道是什么?

我尝试MessageBox从这个事件中完全删除,而是这样做:

 wait.Close();
 lblTotalFileCount.Text = dt.Rows.Count.ToString();

然后处理标签的 TextChanged 事件并检查它是否应该显示 MessageBox ......但我仍然得到与红色框相同的结果。

编辑;另外,我注意到了一件奇怪的事情。在表单加载时,lblTotalFileCount 设置为 0。当此方法运行并说它找到 0 个文件时,它会将 lblTotalFileCount.Text 重新设置为零......哪个没有触发TextChanged 事件?我知道它被设置为与它已经相同的东西,但它仍然在技术上进行了更改。我是否遗漏了某些东西,或者事件是否实际上检查了该条件并在这种情况下“跳过”它?我不得不将标签设置为空字符串......但是假设他们运行应用程序,它被设置为 0,提醒他们,他们进行一些更改,再次运行......仍然是 0,它不会提醒他们。

编辑2;我想也许如果我在 MessageBox 出现之前在第一次编辑中提到的标签的 TextChanged 事件中调用 wait.Close() ,也许它会起作用?没有。同样的问题。然后,如果我再次单击该按钮,表单会因为等待已被释放而崩溃?这是一个表单级别的属性,为什么要处理它?

编辑 3;好吧,如果我在 TextChanged 事件中调用 wait.Dispose,我会得到所需的行为。除了它最小化主应用程序并且只向我显示 MessageBox,除非它后面没有任何东西。的儿子...

4

1 回答 1

0

对 Windows 窗体控件进行线程安全调用。要从另一个线程修改 winform 或控件(BackgroundWorker 会这样做),您应该从主线程进行此调用。在这个问题中,您有答案:如何从 C# 中的另一个线程更新 GUI?

于 2013-11-01T17:20:42.520 回答