因此,从我的应用程序表单中删除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。我不知道怎么做。它的工作原理非常完美,但控件仍保留在表格的中间位置。
答案 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);
}
}
像这样有效,但对我来说很糟糕。