从表单中删除控件

时间:2009-10-24 15:57:53

标签: c# winforms user-controls backgroundworker

因此,从我的应用程序表单中删除Control时出现了一些严重问题。它有点乱,但我不能改变任何东西。我有一个表单,我有一个单独的用户控件。该控件打开一个exe文件,并在加载它的字节时显示一个进度条。这就是问题所在。我使用BackgroundWorker完成所有操作,当调用worker_DoWorkerCompleted方法时,原始表单应显示MessageBox并删除Control。

BackGround_Loader bgLoad = new BackGround_Loader();
bgLoad.Location = new Point(this.Width/2 - bgLoad.Width/2, this.Height/2 - bgLoad.Height/2);
this.Controls.Add(bgLoad);
bgLoad.BringToFront();
bgLoad.AddReferences(this.executableFile, this.SourceReader);
bgLoad.occuredEvent();

首先,我将控件的位置设置为Form本身的中间位置。然后我将控件添加到表单,并将其带到前面。在这些之后,我发送可执行文件的路径和RichTextBox的引用。使用occuredEvent我启动BackgroundWorker本身。这就是我的问题。当bgLoad中的backgroundworker达到DoWorkerCompleted状态时,我应该在表单中显示一个MessageBox。我不知道怎么做。它的工作原理非常完美,但控件仍保留在表格的中间位置。

2 个答案:

答案 0 :(得分:1)

必须在主UI线程上执行UI操作。从后台工作线程中获取的事件(显然)在不同的线程中。

您需要以下代码:

private void backgroundWorker_DoWork(object sender, AlbumInfoEventArgs e)
{
    // Check with an element on the form whether this is a cross thread call
    if (dataGridView.InvokeRequired)
    {
        dataGridView.Invoke((MethodInvoker)delegate { AddToGrid(e.AlbumInfo); });
    }
    else
    {
        AddToGrid(e.AlbumInfo);
    }
}

在这种情况下,AddToGrid是我向DataGridView添加行的方法,但在您的情况下,它将是一个执行您需要执行的操作的方法。

同样适用于backgroundWorker_RunWorkerCompleted方法

请参阅此MSDN example

答案 1 :(得分:0)

我能找到解决问题的方法,但我并不喜欢它。在addReferences方法中,我传递了Form本身和bgLoad类的对象。然后在RunWorkerCompleted中检查控件是否在窗体上,如果是,那么我将其删除。

bgLoad.AddReferences(this, bgLoad, this.executableFile, this.SourceReader);

...
private void worker_DoWorkerCompleted(object sender, DoWorkerEventArgs e) {
    if(this.MainForm.Controls.Contains(this.Control) {
        this.MainForm.Controls.Remove(this.Control);
    }
}

像这样有效,但对我来说很糟糕。