I have a WinForms application and from the main form I am opening a new form and because the new form opening reads details from .xml
file, I am opening this form via different Thread
in order to avoid my UI stuck (the details read could take 1-3 seconds). After I open this form in a different Thread
my form appears in my other screen (I am working with dual screen) although the StartPosition
property is CenterParent
.
When I disable this new Thread
and open the form from within the same Thread
the StartPosition
is CenterParent
.
This is how I am opening my new form:
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");
}
To say it simply: Each stack of windows is related to single thread. So you might have 2 windows each running on different thread. When you open a new window or dialog, it looks at top of the stack of windows in current thread and uses the top as it's parent. In your case frm.ShowDialog();
opens the dialog in different thread than all other windows so it doesn't have a parent it can to relate to.
To fix this, either use manual invoke (like in How to update the GUI from another thread in C#?) or move opening of the dialog into RunWorkerCompleted
event, that is automatically synchronized to run on main UI thread.