调用ShowDialog()后如何继续执行代码

Form.ShowDialog()方法导致代码暂停,直到新调用的窗体关闭。 我需要在调用ShowDialog()方法后继续运行代码。 我用谷歌搜索并阅读有关使用backgroundworker的内容? 但这是我第一次听说过,从未使用过它。

Form2 form2this = new Form2(); form2this.ShowDialog(); MessageBox.Show("Something"); 

单击按钮后执行此代码,如何仍然调用ShowDialog以防止用户与主窗体交互,但仍然允许主窗体继续其工作?

很抱歉,如果已经讨论过,但我发现的一切似乎都很难执行这么简单的任务。 我实际上很惊讶它不包含在SHowDialog方法中。 例如ShowDialog()。继续会很酷。

  • 如果您只想让代码继续而不是阻塞,直到弹出窗口关闭,请考虑使用Show而不是ShowDialog

  • 如果您希望在子表单启动时让父表单执行某些操作,那么可以使用BackgroundWorker(或者只是手动启动新的线程/任务)。 了解更多有关该任务的内容将会有所帮助。 如果你需要与主表格或儿童表格互动,那对我来说似乎有点麻烦; 如果你只是需要做一些没有UI交互的后台任务,那么这是正确的思路。

  • 另一种可能性是你想要做的事情应该是以子forms完成的,而不是父forms。

只要在打开模式对话框的过程中执行异步操作,就可以像下面所示一样简单地操作,假设button1_Click()是按钮的事件处理程序。

 private async void button1_Click(object sender, EventArgs e) { // create and display modal form Form2 modalForm = new Form2(); BeginInvoke((Action)(() => modalForm.ShowDialog())); // do your async background operation await DoSomethingAsync(); // close the modal form modalForm.Close(); } private async Task DoSomethingAsync() { // example of some async operation....could be anything await Task.Delay(10000); } 

我发现当我使用建议使用Show()的解决方案时,我可能会在我想要模态的对话框最终在主要表单后面,在应用程序之间来回切换的情况下结束。 当我使用上述解决方案时,这种情况从未发生

是否有任何理由不能将此代码作为Form2类的一部分? 或者使用非modal dialog? 你可以使用后台工作者甚至像计时器一样简单的东西,但看起来有点矫枉过正?

运行异步调用以显示模态。 这是wpf中的一个例子:

 private Window waitView; ///  /// Closes a displayed WaitView from code. ///  public void CloseWaitView() { if(waitView != null) { // Work on the gui Thread of waitView. waitView.Dispatcher.Invoke(new Action(() => close())); } } ///  /// Closes a displayed WaitView and releases waitView-Instance. ///  private void close() { waitView.Close(); waitView = null; } ///  /// Showes a modal WaitView (Window). ///  public void ShowWaitView() { // instance a new WaitViewWindow --> your Window extends Window-Class waitView = new WaitViewWindow(); // prepare a operation to call it async --> your ShowDialog-call var asyncCall = new Action(() => waitView.Dispatcher.Invoke( new Action(() => waitView.ShowDialog()) )); // call the operation async // Argument 1 ar: // ar means IAsyncResult (what should be done, when come back from ShowDialog --> // remove view memory with set waitView to null or ... dispose // the second argument is an custom parameter you can set to use in ar.AsyncState asyncCall.BeginInvoke(ar => waitView = null, null); // all from here is done during ShowDialog ... } 

这是我的方式,很丑,但我没有更好的主意。

 private void AppUiMain_Shown(object sender, EventArgs e) { var loading = new AppUiLoading(); loading.Shown += (o, args) => { bool isLoading = true; loading.Top = (int)(loading.Top * 1.16); Application.DoEvents();//refresh ui EventHandler ehr = null; EventHandler ehe = null; ehr = (ss, ee) => { App.Instance.Ready -= ehr; App.Instance.Error -= ehe; isLoading = false; }; ehe = (ss, ee) => { loading.Text = "Error"; loading.ShowAbortButton("Error occur"); }; App.Instance.Error += ehe; App.Instance.Ready += ehr; InitApp(); //HACK: find a better way to `refresh' main form Application.DoEvents(); this.Height++; this.Height--; //HACK: find a better way to keep message looping on ShowDialog while (isLoading) Application.DoEvents(); loading.Close(); }; loading.ShowDialog(this); } 

继续执行代码而不关闭模式对话框WindowsFormsSynchronizationContext.Current.Post( – => {“Your code”},null); 可以使用。 在这里你可以找到更多细节 –

http://newapputil.blogspot.in/2015/05/continue-executing-code-after-calling.html

我想下一个异步ShowDialog解决方案:

 public bool DialogResultAsync { get; private set; } public async Task ShowDialogAsync() { var cts = new CancellationTokenSource(); // Attach token cancellation on form closing. Closed += (object sender, EventArgs e) => { cts.Cancel(); }; Show(); // Show message without GUI freezing. try { // await for user button click. await Task.Delay(Timeout.Infinite, cts.Token); } catch (TaskCanceledException) { } } public void ButtonOkClick() { DialogResultAsync = true; Close(); } public void ButtonCancelClick() { DialogResultAsync = false; Close(); } 

在主窗体中,您必须使用以下代码:

 public async void ShowDialogAsyncSample() { var msg = new Message(); if (await msg.ShowDialogAsync()) { // Now you can use DialogResultAsync as you need. System.Diagnostics.Debug.Write(msg.DialogResultAsync); } }