web-dev-qa-db-fra.com

Comment continuer à exécuter le code après avoir appelé showdialog ()

la méthode FORM.SHOWDIALOG () provoque une halte du code jusqu'à ce que le formulaire nouvellement appelé soit fermé. J'ai besoin du code pour continuer à courir après que la méthode ShowDialog () est appelée. J'ai Googled et lisez à propos de l'utilisation d'un bus d'arrière-plan? Mais c'est la première fois que j'en ai entendu parler de cela et je ne l'ai jamais utilisé auparavant.

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

Ce code est exécuté après avoir cliqué sur un bouton, comment puis-je toujours appeler Showdialog pour empêcher l'utilisateur d'interagir avec le formulaire principal, mais permettant toujours à la forme principale de continuer son travail?

Désolé si c'est discuté mais tout ce que j'ai trouvé semble extrêmement difficile d'effectuer une tâche aussi simple. Je suis en fait surpris que ce n'est pas inclus dans la méthode showdialog. par exemple showdialog (). Continuer serait cool.

17
Seth
  • Si vous voulez juste que le code continue au lieu de bloquer jusqu'à ce que la fenêtre contextuelle soit fermée, envisagez d'utiliser Show au lieu de ShowDialog.

  • Si vous avez une action que vous souhaitez avoir la forme parent de faire pendant que le formulaire enfant est en hausse, alors oui, il pourrait être approprié d'utiliser un travailleur d'arrière-plan (ou simplement de démarrer manuellement un nouveau fil/tâche). Il serait utile de savoir plus sur ce que cette tâche est cependant. Si vous devez interagir avec la forme principale ou la forme de l'enfant, alors cela me semble être des problèmes; Si vous avez juste besoin de faire une tâche d'arrière-plan sans interaction de l'interface utilisateur, c'est la bonne ligne de pensée.

  • Une autre possibilité est que ce que vous voulez faire, il suffit de faire quelque chose sur la forme de l'enfant, plutôt que de la forme parent.

17
Servy

Tant que vous faites des opérations asynchrones pendant le temps que la boîte de dialogue modale est ouverte, vous pouvez le faire comme indiqué ci-dessous, en supposant que Bouton1_Click () est le gestionnaire d'événements pour un bouton.

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

J'ai constaté que lorsque j'avais utilisé la solution suggérée d'utiliser le spectacle (), je pourrais me retrouver dans des cas où la boîte de dialogue que je voulais être modale se retrouverait derrière la forme principale, après la mise sous tension des applications. Cela n'arrive jamais lorsque j'utilise la solution ci-dessus.

8
Joe Savage

Y a-t-il une raison pour laquelle vous ne pouvez pas avoir ce code dans le cadre de la classe Form2? Ou utilisez une boîte de dialogue non modale? Vous pouvez utiliser un ouvrier d'arrière-plan ou même quelque chose de simple comme une minuterie, mais semble être trop excitée?

0
Fergal Moran

C'est mon chemin, si moche mais je n'ai aucune meilleure idée.

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

Exécutez un appel ASYNC pour montrer modal. Voici un exemple dans 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

Pour poursuivre l'exécution du code sans fermeture de la boîte de dialogue modale WindowsFormsSynchronizationContext.Current.post (- => {"Votre code"}, null); peut être utilisé. Ici vous pouvez trouver plus de détails -

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

0
nvivekgoyal