views:

49

answers:

2

Hello, 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.

+1  A: 

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

ChrisF
I guess I wasn't clear. Let me make my question more accurate. I have two classes. One for the main Form of my application, and another for a Control to load files with a simple form which has a progress bar on it. The main form calls the control when there's an openFile event. With it the Control's form is generated. The control uses a backgroundworker to load the files. What I want to do, is to remove the control when the RunWorkerCompleted event occured in the Control itself. So my problem is: I have to remove the control from the form.Controls but from the control itself. it's kinda messy.
Frost
I need something like this:public partial class Form1 { .... BackGround_Loader bgLoad = new BackGround_Loader(); bgLoad.AddReferences(this.executable, this.SourceReader); bgLoad.occireEvent(); //Start the BackgroundWorker}public partial class BackGround_Loader { private BackgroundWorker worker = new BackGroundWorker(); ... private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { Form1.Controls.Remove(bgLoad); //I should do something like this but in this concept it won't work. I don't know how can it be done. }}
Frost
@Frost - I'd update your question with this code - it's nearly impossible to read in comments.
ChrisF
A: 

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.

Frost