C# 为什么在不同的线程中打开新表单后,启动位置会有所不同?
我有一个WinForms应用程序,我正在从主窗体打开一个新窗体,因为新窗体打开时从C# 为什么在不同的线程中打开新表单后,启动位置会有所不同?,c#,.net,multithreading,winforms,backgroundworker,C#,.net,Multithreading,Winforms,Backgroundworker,我有一个WinForms应用程序,我正在从主窗体打开一个新窗体,因为新窗体打开时从.xml文件中读取详细信息,所以我正在通过不同的线程打开此窗体,以避免我的UI卡住(读取详细信息可能需要1-3秒)。在不同的线程中打开此表单后我的表单将出现在另一个屏幕中(我使用的是双屏幕),尽管StartPosition属性是CenterParent。 当我禁用这个新的线程并从同一线程中打开表单时,起始位置为中心父级 以下是我如何打开我的新表单: try {
.xml
文件中读取详细信息,所以我正在通过不同的线程打开此窗体,以避免我的UI卡住(读取详细信息可能需要1-3秒)。在不同的线程中打开此表单后
我的表单将出现在另一个屏幕中(我使用的是双屏幕),尽管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()代码>在与所有其他窗口不同的线程中打开对话框,因此它没有可以关联的父窗口
要解决此问题,请使用手动调用(如中)或将对话框的打开移动到RunWorkerCompleted
事件中,该事件将自动同步到主UI线程上运行。简单地说:每个窗口堆栈都与单个线程相关。因此,您可能有两个窗口,每个窗口在不同的线程上运行。当您打开一个新窗口或对话框时,它会查看当前线程中窗口堆栈的顶部,并将顶部用作其父窗口。在您的例子中,frm.ShowDialog()代码>在与所有其他窗口不同的线程中打开对话框,因此它没有可以关联的父窗口
要解决此问题,请使用手动调用(如中)或将对话框的打开移动到RunWorkerCompleted
事件中,该事件将自动同步到主UI线程上运行。简单地说:每个窗口堆栈都与单个线程相关。因此,您可能有两个窗口,每个窗口在不同的线程上运行。当您打开一个新窗口或对话框时,它会查看当前线程中窗口堆栈的顶部,并将顶部用作其父窗口。在您的例子中,frm.ShowDialog()代码>在与所有其他窗口不同的线程中打开对话框,因此它没有可以关联的父窗口
要解决此问题,请使用手动调用(如中)或将对话框的打开移动到RunWorkerCompleted
事件中,该事件将自动同步到主UI线程上运行。简单地说:每个窗口堆栈都与单个线程相关。因此,您可能有两个窗口,每个窗口在不同的线程上运行。当您打开一个新窗口或对话框时,它会查看当前线程中窗口堆栈的顶部,并将顶部用作其父窗口。在您的例子中,frm.ShowDialog()代码>在与所有其他窗口不同的线程中打开对话框,因此它没有可以关联的父窗口
要解决此问题,请使用手动调用(如中)或将对话框的打开移动到RunWorkerCompleted
事件中,该事件将自动同步到主UI线程上运行