-->

如何继续调用的ShowDialog后执行代码()(How to continue executing

2019-07-03 14:02发布

所述Form.ShowDialog()方法将导致被停止的代码,直到新称为形式被关闭。 我需要的代码的ShowDialog()方法被调用后继续运行。 我用Google搜索和阅读有关使用BackgroundWorker的? 但是,这是我第一次听说过这一点,从来没有使用过它。

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

该代码被点击一个按钮后执行的,我怎么能还叫的ShowDialog以防止用户从与主窗体交互,但仍然允许的主要形式继续开展工作?

很抱歉,如果它被讨论,但一切,我发现似乎很难执行这样一个简单的任务。 我其实感到惊讶它不包括在ShowDialog方法。 例如ShowDialog的()。继续会很酷。

Answer 1:

  • 如果你只是想代码继续而不是阻塞,直到弹出关闭考虑使用上的Show ,而不是ShowDialog

  • 如果你有,你想有父窗体做,而孩子的形式是一些行动,那么,它可能是适合使用的BackgroundWorker(或只是手动启动一个新的线程/任务)。 这将有助于了解更多有关的任务是什么,但。 如果你需要用的主要形式,或子窗体交互,那么这似乎是麻烦我。 如果您只是需要做一些后台任务,没有用户界面交互,那么这是思想的正确的路线。

  • 另一种可能是你想做的事真的只是应该是在孩子的形式完成的,而不是父窗体。



Answer 2:

只要你在该模式对话框被打开的时间做异步操作,你可以简单地做到这一点,如下图所示,假设的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);
}

我发现,当我使用的建议使用展()的解决方案,我可以在该对话框我想是模式最终会主要形式的背后,来回切换应用程序之间的情况后结束。 当我使用上面的解决方案,它从未发生过。



Answer 3:

是否有任何理由,你为什么不能有这样的代码为窗体2类的一部分? 或者使用一个无模式对话框? 你可以使用一个后台工作,甚至一些简单的像一个计时器,但似乎是大材小用?



Answer 4:

运行一个异步调用显示模式。 在这里,在WPF一个例子:

private Window waitView;

/// <summary>
/// Closes a displayed WaitView from code.
/// </summary>
public void CloseWaitView()
{
  if(waitView != null)
  {
     // Work on the gui Thread of waitView.
     waitView.Dispatcher.Invoke(new Action(() => close()));
  }
}

/// <summary>
/// Closes a displayed WaitView and releases waitView-Instance.
/// </summary>    
private void close()
{
   waitView.Close();
   waitView = null;
}   

/// <summary>
/// Showes a modal WaitView (Window).
/// </summary>
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 ...
}


Answer 5:

这是我的路,这么难看,但我没有更好的主意。

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);
}


Answer 6:

要继续执行代码,而不关闭模态对话框WindowsFormsSynchronizationContext.Current.Post( - => { “您的代码”},NULL); 可以使用。 在这里,你可以找到更多的细节 -

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



Answer 7:

我想对于异步未来解决方案ShowDialog

public bool DialogResultAsync
{
    get;
    private set;
}

public async Task<bool> 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);
    }
}


文章来源: How to continue executing code after calling ShowDialog()