web-dev-qa-db-ja.com

ShowDialog()を呼び出した後、コードの実行を継続する方法

form.ShowDialog()メソッドは、新しく呼び出されたフォームが閉じられるまでコードを停止させます。 ShowDialog()メソッドが呼び出された後もコードを実行し続ける必要があります。私はググってbackgroundworkerの使用について読みましたか?しかし、それを聞いたのはこれが初めてで、これまでに使用したことがありません。

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

このコードはボタンをクリックした後に実行されますが、ShowDialogを呼び出して、ユーザーがメインフォームを操作できないようにしながら、メインフォームが作業を続行できるようにするにはどうすればよいですか?

それが議論された場合は申し訳ありませんが、私が見つけたすべてがそのような単純なタスクを実行することは非常に難しいようです。 SHowDialogメソッドに含まれていないことに実際に驚いています。たとえばShowDialog()。Continueはクールです。

17
Seth
  • ポップアップが閉じるまでブロックせずにコードを続行したい場合は、Showの代わりにShowDialogを使用することを検討してください。

  • 子フォームが起動している間に親フォームに実行させたいアクションがある場合は、はい、BackgroundWorkerを使用する(または、新しいスレッド/タスクを手動で開始する)のが適切な場合があります。そのタスクが何であるかについてもっと知っておくと役に立ちます。メインフォームまたは子フォームを操作する必要がある場合、それは私には問題のようです。 UIインタラクションなしでバックグラウンドタスクを実行する必要があるだけなら、これは正しい考えです。

  • もう1つの可能性は、実際に実行したいことは、親フォームではなく子フォームで行われることだけであるということです。

17
Servy

モーダルダイアログが開いている間に非同期操作を行う限り、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()の使用を提案したソリューションを使用すると、モーダルにしたいダイアログがアプリ間で切り替えた後、メインフォームの後ろに表示される場合があることに気付きました。上記のソリューションを使用すると、それは決して起こりません。

8
Joe Savage

このコードをForm2クラスの一部として使用できない理由はありますか?または非モーダルダイアログを使用しますか?バックグラウンドワーカーを使用することも、タイマーのような単純なものを使用することもできますが、やりすぎのように見えますか?

0
Fergal Moran

これは私のやり方なので、醜いですが、私にはこれ以上の考えはありません。

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

非同期呼び出しを実行してモーダルを表示します。ここで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 ...
}
0
Björn Frohberg

モーダルダイアログを閉じずにコードの実行を継続するにはWindowsFormsSynchronizationContext.Current.Post(-=> {"Your code"}、null);に使える。ここで詳細を確認できます-

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

0
nvivekgoyal