You can use a separate thread (as below), but this is getting into dangerous territory - you should only go near this option if you understand the implications of threading (synchronization, cross-thread access, etc):
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Button loadB, loadC;
Form formA = new Form {
Text = "Form A",
Controls = {
(loadC = new Button { Text = "Load C", Dock = DockStyle.Top}),
(loadB = new Button { Text = "Load B", Dock = DockStyle.Top})
}
};
loadC.Click += delegate {
Form formC = new Form { Text = "Form C" };
formC.Show(formA);
};
loadB.Click += delegate {
Thread thread = new Thread(() => {
Button loadD;
Form formB = new Form {
Text = "Form B",
Controls = {
(loadD = new Button { Text = "Load D",
Dock = DockStyle.Top})
}
};
loadD.Click += delegate {
Form formD = new Form { Text = "Form D"};
formD.ShowDialog(formB);
};
formB.ShowDialog(); // no owner; ShowDialog to prevent exit
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
};
Application.Run(formA);
}
(obviously, you wouldn't actually structure the code like the above - this is just the shortest way of showing the behavior; in real code you'd have a class per form etc)