在sperate线程中显示加载窗口时,主窗口窗体失去焦点。 [英] Main window form is losing focus when showing loading window in sperate thread.

查看:184
本文介绍了在sperate线程中显示加载窗口时,主窗口窗体失去焦点。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在单独的帖子中显示加载窗口表单。我的问题是当我的任务结束时我通过调用Close()方法关闭窗口但是我的主窗口失去焦点以获得焦点我需要从任务栏中选择窗体。

这里是我的代码:



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 :

  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.





请帮助我..我也通过调用this.Focus()进行检查CloseLoading()结束时的方法;方法,但它不工作。



Please help me.. i have also checked by calling this.Focus() method at the end of CloseLoading(); method but its not working.

推荐答案

我建​​议你做的第一件事是阅读Jon Skeet关于WinForms中线程的文章:[ ^ ];它已经有几年了,但却是经典之作。



其次,我建议你意识到虽然你可以逃避现在正在做的事情,没有实现真正的回调机制,允许你更新窗体(主窗体,我假设)UI而不产生Skeet的文章中描述的类型的跨线程UI更新错误,你将无法避免再次单击主窗体重新建立焦点。



那么,该怎么办?



我建议你考虑在这种情况下使用BackGroundWorker,它提供了一个方便的方法来在线程完成时通知你。有两篇CodeProject文章可以帮助您理解'BackGroundWorker:[ ^ ],[ ^ ],当然,MSDN有一个很好的教程:[ ^ ]。



或者,你可以实现类似这个例子的方法,它使用'MethodInvoker方法在没有错误的情况下向UI线程获取告别消息,但是当次要表格/线程退出时仍然需要你点击主表格:



1.主窗体'Form1:a TextBox',textBox1;一个按钮,'button1
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
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有一个TextBox,'textBox1。我选择使用BorderStyle.FixedToolWindow创建Form2,没有'Text,没有'CloseButton。

2. Form2: Form2 has a TextBox, 'textBox1. I chose to make Form2 with BorderStyle.FixedToolWindow, no 'Text, and no 'CloseButton.

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


对于表单,您不应该关注但是要激活它:http://msdn.microsoft.com/en-us /library/system.windows.forms.form.activate%28v=vs.110%29.aspx [ ^ ]。



但是,你的问题可能会更深层次。目前尚不清楚为什么要首先停用表单,以及是否正确使用带有UI的线程。如果您解释所有必要的细节,您可以获得更多帮助。



-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


这篇关于在sperate线程中显示加载窗口时,主窗口窗体失去焦点。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆