以异步方式打开第二个winform,但仍然表现为父表单的子项?

我正在创建一个应用程序,我想实现一个进程窗口,该窗口在进行冗长的过程时出现。

我创建了一个标准的Windows窗体项目,我使用默认窗体创建了我的应用程序。 我还创建了一个新表单作为进度窗口。

使用以下命令打开进度窗口(在函数中)时出现问题:

ProgressWindow.ShowDialog(); 

遇到这个命令时,焦点在进度窗口上,我假设它现在是正在处理事件的主循环的窗口。 缺点是它阻止了我在主窗体中执行冗长的操作。

如果我使用以下命令打开进度窗口:

 ProgressWindow.Show(); 

然后窗口正确打开,现在不会阻止主窗体的执行,但它不会作为子窗口(模态)窗口,即允许选择主窗体,不以父窗口为中心等。 。

我有什么想法可以打开一个新窗口,但继续在主窗体中处理?

您可能在单独的工作线程中开始冗长的操作(例如,使用后台工作程序)。 然后使用ShowDialog()显示您的表单,并在完成该线程后关闭您正在显示的对话框。

这是一个示例 – 在此我假设您有两种forms( Form1Form2 )。 在Form1我从工具箱中提取了一个BackgroundWorker 。 然后我将BackgroundWorkerRunWorkerComplete事件连接到我的表单中的事件处理程序。 以下是处理事件并显示对话框的代码:

 public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { Thread.Sleep(5000); e.Result = e.Argument; } private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { var dlg = e.Result as Form2; if (dlg != null) { dlg.Close(); } } private void button1_Click(object sender, EventArgs e) { var dlg = new Form2(); this.backgroundWorker1.RunWorkerAsync(dlg); dlg.ShowDialog(); } } 

我为另一个项目实现了与此类似的东西。 此表单允许您从工作线程中弹出模式对话框:

 public partial class NotificationForm : Form { public static SynchronizationContext SyncContext { get; set; } public string Message { get { return lblNotification.Text; } set { lblNotification.Text = value; } } public bool CloseOnClick { get; set; } public NotificationForm() { InitializeComponent(); } public static NotificationForm AsyncShowDialog(string message, bool closeOnClick) { if (SyncContext == null) throw new ArgumentNullException("SyncContext", "NotificationForm requires a SyncContext in order to execute AsyncShowDialog"); NotificationForm form = null; //Create the form synchronously on the SyncContext thread SyncContext.Send(s => form = CreateForm(message, closeOnClick), null); //Call ShowDialog on the SyncContext thread and return immediately to calling thread SyncContext.Post(s => form.ShowDialog(), null); return form; } public static void ShowDialog(string message) { //Perform a blocking ShowDialog call in the calling thread var form = CreateForm(message, true); form.ShowDialog(); } private static NotificationForm CreateForm(string message, bool closeOnClick) { NotificationForm form = new NotificationForm(); form.Message = message; form.CloseOnClick = closeOnClick; return form; } public void AsyncClose() { SyncContext.Post(s => Close(), null); } private void NotificationForm_Load(object sender, EventArgs e) { } private void lblNotification_Click(object sender, EventArgs e) { if (CloseOnClick) Close(); } } 

要使用,您需要从GUI线程中的某个位置设置SyncContext:

 NotificationForm.SyncContext = SynchronizationContext.Current; 

另外一个选项:

使用ProgressWindow.Show()并自己实现模态窗口行为。 parentForm.Enabled = false ,自己定位表单等。