从表单中删除控件

发布于 2024-08-09 15:53:27 字数 728 浏览 6 评论 0原文

因此,我在从应用程序的表单中删除控件时遇到了一些严重的问题。事情有点乱,但我无法改变任何事情。我有一个表单和一个单独的用户控件。该控件打开一个 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();

首先,我将控件的位置设置为窗体本身的中间。然后我将控件添加到窗体中,并将​​其置于最前面。之后,我发送可执行文件的路径和 RichTextBox 对此的引用。通过发生的事件,我启动了BackgroundWorker本身。我的问题来了。当 bgLoad 中后台工作人员达到 DoWorkerCompleted 状态时,我应该在表单中显示一个 MessageBox。拜托,我不知道该怎么做。它工作得非常完美,但是控件仍然位于窗体的中间。

So I've got some serious problems with removing a Control from a Form of my application. It's kinda messed up but I can't change anything. I have a form and I have a separated user Control. The control opens an exe file and shows a progress bar while loading it's bytes. And here comes the problem. I do all of it with a BackgroundWorker and when the worker_DoWorkerCompleted method is called the original form should show a MessageBox and remove the 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();

At first I set the control's location to be in the middle of the Form itself. Then I add the control to the form, and bring it to the front. After these I send the path of the executable and a RichTextBox's reference to this. With the occuredEvent I start the BackgroundWorker itself. And here comes my problem. I should show a MessageBox in the Form when the in the bgLoad the backgroundworker gets to the DoWorkerCompleted status. Kindly I have no idea how to do it. It works just perfect however the control stays in the middle of the form.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

拥抱影子 2024-08-16 15:53:27

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 示例

UI actions must be performed on the main UI thread. The events that get raised from the background worker thread are (obviously) in a different thread.

You need something like the following code:

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

In this case AddToGrid is my method for adding a row to a DataGridView, but in your case it will be a method that does what you need to do.

Similarly for the backgroundWorker_RunWorkerCompleted method

See this MSDN example

稚气少女 2024-08-16 15:53:27

我可以找到解决问题的方法,但我不太喜欢它。在 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);
    }
}

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

I could find a way to solve the problem but I don't really like it. In the addReferences method I pass the Form itself and an object of the bgLoad class. Then in the RunWorkerCompleted I check if the control is on the form and if it is then I remove it.

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

Like this it works but it's awful for me.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文