我有一个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");
}
答案 0 :(得分:3)
简单地说:每个窗口堆都与单个线程相关。所以你可能有2个窗口,每个窗口在不同的线程上运行当您打开一个新窗口或对话框时,它会查看当前线程中窗口堆栈的顶部,并使用顶层作为其父级。在你的情况下,frm.ShowDialog();
在与所有其他窗口不同的线程中打开对话框,因此它没有可以与之关联的父级。
要解决此问题,请使用手动调用(例如在How to update the GUI from another thread in C#?中)或将对话框打开到RunWorkerCompleted
事件,该事件会自动同步以在主UI线程上运行。