在不同的帖子中打开新表单后,为什么启动位置不同?

时间:2014-05-08 09:21:24

标签: c# .net multithreading winforms backgroundworker

我有一个WinForms应用程序,从主窗体我打开一个新表单,因为新表单打开从.xml文件中读取详细信息,我将通过不同的Thread打开此表单,以便避免我的UI卡住(阅读的详细信息可能需要1-3秒)。在我以不同的Thread打开此表单后,我的其他屏幕中出现了我的表单(我正在使用双屏幕),尽管StartPosition属性为CenterParent。 当我停用此新Thread并在同一Thread内打开表单时,StartPositionCenterParent

这就是我打开新表格的方式:

       try
        {
            BackgroundWorker backgroundWorker = new BackgroundWorker();
            backgroundWorker.WorkerReportsProgress = true;
            backgroundWorker.DoWork += new DoWorkEventHandler(
            (s3, e3) =>
            {
                string xmlFile = Path.Combine(
                    Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
                    @"file.xml");
                XmlDocument doc = new XmlDocument();
                doc.Load(xmlFile);
                MyForm frm = new MyForm(doc);
                frm.ShowDialog();
                e3.Result = webmails;
            });

            backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(
                (s3, e3) =>
                {
                    MyForm frm = (MyForm)e3.Result;                        
                    if (webmails.DialogResult == DialogResult.OK)
                    {
                        // bla bla
                    }
                }
                );

            backgroundWorker.RunWorkerAsync();

        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Error");
        }

1 个答案:

答案 0 :(得分:3)

简单地说:每个窗口堆都与单个线程相关。所以你可能有2个窗口,每个窗口在不同的线程上运行当您打开一个新窗口或对话框时,它会查看当前线程中窗口堆栈的顶部,并使用顶层作为其父级。在你的情况下,frm.ShowDialog();在与所有其他窗口不同的线程中打开对话框,因此它没有可以与之关联的父级。

要解决此问题,请使用手动调用(例如在How to update the GUI from another thread in C#?中)或将对话框打开到RunWorkerCompleted事件,该事件会自动同步以在主UI线程上运行。