Click here to Skip to main content
15,867,453 members
Please Sign up or sign in to vote.
2.00/5 (1 vote)
See more:
Hi, I am showing a loading window form in separate thread. My problem is when my task is over i am closing the window by calling Close() method but my main window is losing focus for getting focus back i need to select the form from the task bar.
Here is my code :

C#
  Thread thread = new Thread(new ThreadStart(ShowLoading));
  thread.Start();

//perform heavy task

CloseLoading(); // this method will close the loading form

  this.Focus() // its not working.

//Note : after closing the loading form. the main form is losing focus.


Please help me.. i have also checked by calling this.Focus() method at the end of CloseLoading(); method but its not working.
Posted
Comments
Sergey Alexandrovich Kryukov 29-Dec-14 3:17am    
Do you use Control.Invoke or Control.BeginInvoke? Why would you grab focus from the main form (more exactly, deactivate it)?
—SA

The first thing I suggest you do is read Jon Skeet's essay on threading in WinForms: [^]; it's a few years old, but is a "classic."

Second, I suggest you realize that while you can "get away" with what you are doing now, without implementing a real "callback mechanism" that allows you to update the Form (the Main Form, I assume) UI without producing a cross-thread UI update error of the type described in Skeet's essay, you are not going to be able to avoid clicking on the Main Form again to re-establish Focus.

So, what to do ?

I recommend you consider using a BackGroundWorker in this case, which provides a handy method to notify you when the Thread has completed. There are two CodeProject articles that can assist you in understanding 'BackGroundWorker: [^], [^], and, of course, MSDN has a good tutorial: [^].

Or, you can implement something like this example which does use the 'MethodInvoker method to get a "farewell message" to the UI Thread without an error, but will still require you to click on the Main Form when the secondary Form/Thread exits:

1. the Main Form 'Form1: a TextBox, 'textBox1; a Button, 'button1
C#
using System;
using System.Collections.Generic;
using System.Threading;
using System.Windows.Forms;

namespace SecondaryFormByThread
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        Form2 instanceOfForm2;
        Thread thread;

        // this will hold the Data generated in Form2
        List<int> FormData = new List<int>();

        // show the instance of Form2 which will generate the data
        private void button1_Click(object sender, EventArgs e)
        {
            ShowLoading();
        }

        private void ShowLoading()
        {
            instanceOfForm2 = new Form2();

            // inject the reference to the List<int> in Form1 into the matching List<int> Form2
            instanceOfForm2.Form2Data = FormData;

            // inject the 'DataComplete method in Form1 into the matching Action in Form2
            instanceOfForm2.DataComplete = DataComplete;

            // use 'ShowDialog so Form2 will remain visible
            thread = new Thread(new ThreadStart(() => instanceOfForm2.ShowDialog()));
            
            thread.Start();
        }

        private void DataComplete(bool closeThreadOkay)
        {
           textBox1.Text = string.Format("finished: data count = {0}", FormData.Count);

           // any code after this call will not be executed !
           if (thread.IsAlive && closeThreadOkay) thread.Abort();
        }
    }
}
2. Form2: Form2 has a TextBox, 'textBox1. I chose to make Form2 with BorderStyle.FixedToolWindow, no 'Text, and no 'CloseButton.
C#
using System;
using System.Collections.Generic;
using System.Threading;
using System.Windows.Forms;

namespace SecondaryFormByThread
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
            this.TopLevel = true;
        }

        // list injected by Form1
        public List<int> Form2Data { set; get; }

        // method injected by Form1
        public Action<bool> DataComplete;

        private void Form2_Load(object sender, EventArgs e)
        {
            this.TopLevel = true;
        }

        // keep it simple ?: let Form2 appear 'inactive
        protected override bool ShowWithoutActivation
        {
            get { return true; }
        }

        private void Form2_Shown(object sender, EventArgs e)
        {
            // some kind of code that creates the data ...
            for (int i = 0; i < 100; i++)
            {
                // add to the Data that remain usable in 'Form1
                Form2Data.Add(i);

                Thread.Sleep(50);

                // simulate some kind of progress report
                textBox1.AppendText("-");
            }

            // use of invoke lets us do something in Form1's UI
            // without a cross-thread UI update error
            Invoke(new MethodInvoker(Finish));
        }

        private void Finish()
        {
            // call the method injected by Form1
            DataComplete(true);
        }
    }
}
 
Share this answer
 
v2
Comments
Sergey Alexandrovich Kryukov 29-Dec-14 11:54am    
This is all good and looks correct, but my question is: how did you deduce, based on the very scarce information on the OP's code, what was the reason for deactivation of the form? If someone shows and activates some form, and then removes it, it could look ugly but the form underneath would otherwise be activated again?
—SA
For a form, you should not focus but activate it: http://msdn.microsoft.com/en-us/library/system.windows.forms.form.activate%28v=vs.110%29.aspx[^].

However, your problem could be deeper. It's not clear why would you deactivate the form in first place, and if you are using threading with UI correctly. If you explain all essential detail, you can get more help.

—SA
 
Share this answer
 
Comments
BillWoodruff 29-Dec-14 7:53am    
My vote of #1. Activation will make no difference in this case. This "solution" contributes nothing to the OP's concern.
Sergey Alexandrovich Kryukov 29-Dec-14 11:55am    
How could you possibly know that? I put appropriate note that I recommend to do something else. Please see my comment to your solution (which itself can be useful). Are you getting the idea?
—SA
Kar_Malay 12-Dec-20 14:46pm    
Activation idea, solve a similar kind of my issue. thanks

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900