为什么我在不同的线程中打开新窗体后启动位置不同
本文关键字:窗体 位置 新窗体 启动 线程 为什么 | 更新日期: 2023-09-27 18:02:14
我有一个WinForms应用程序,从主表单我打开一个新表单,因为新表单打开从.xml
文件读取详细信息,我通过不同的Thread
打开这个表单,以避免我的UI卡住(详细信息读取可能需要1-3秒)。当我在不同的Thread
中打开此表单时,我的表单出现在我的其他屏幕中(我正在使用双屏幕),尽管StartPosition
属性是CenterParent
。当我禁用这个新的Thread
并从相同的Thread
中打开表单时,StartPosition
是CenterParent
。
下面是我打开新表单的方式:
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");
}
简单地说:每个窗口堆栈都与单个线程相关。因此,您可能有两个窗口,每个窗口在不同的线程上运行。当你打开一个新窗口或对话框时,它会查看当前线程中窗口堆栈的顶部,并使用顶部作为它的父线程。在您的情况下,frm.ShowDialog();
在不同的线程中打开对话框,而不是所有其他窗口,因此它没有可以关联的父线程。
要解决这个问题,要么使用手动调用(如在c#中如何从另一个线程更新GUI ?)或将对话框的打开移动到RunWorkerCompleted
事件,这将自动同步到主UI线程上运行。