Question

Je suis en train d'écrire une application (c # + WPF) où toutes les boîtes de dialogue de style modal sont mises en œuvre en tant que UserControl sur le dessus d'une grille translucide couvrant la Window principale. Cela signifie qu'il n'y a qu'un seul Window et maintient l'apparence de toutes les applications entreprises.

Pour afficher une MessageBox, la syntaxe est la suivante:

CustomMessageBox b = new CustomMessageBox("hello world");
c.DialogClosed += ()=>
{
   // the rest of the function
}
// this raises an event listened for by the main window view model,
// displaying the message box and greying out the rest of the program.
base.ShowMessageBox(b); 

Comme vous pouvez le voir, non seulement est le flux d'exécution en fait inversée, mais son horriblement bavard par rapport à la version .NET classique:

MessageBox.Show("hello world");
// the rest of the function

Ce que je cherche vraiment est un moyen de ne pas revenir de base.ShowMessageBox jusqu'à ce que la boîte de dialogue qu'elle a été soulevée événement fermé, mais je ne peux pas voir comment il est possible d'attendre cela sans accrocher le fil de l'interface graphique et empêchant ainsi l'utilisateur jamais en cliquant sur OK. Je sais que je peux prendre une fonction de délégué en tant que paramètre à la fonction ShowMessageBox qui empêche l'inversion de type d'exécution, mais provoque toujours une syntaxe folle / indenter.

Suis-je manque quelque chose d'évident ou est-il un moyen standard de faire cela?

Était-ce utile?

La solution

Vous pouvez jeter un oeil à cet article sur CodeProject et < a href = "http://msdn.microsoft.com/en-us/library/aa969773.aspx#Creating_a_Modal_Custom_Dialog_Box" rel = "noreferrer"> cet article sur MSDN. Le premier article vous guide à travers la création manuelle d'un dialogue modal de blocage, et le second article illustre comment créer des dialogues personnalisés.

Autres conseils

La façon de le faire est d'utiliser un DispatcherFrame objet .

var frame = new DispatcherFrame();
CustomMessageBox b = new CustomMessageBox("hello world");
c.DialogClosed += ()=>
{
    frame.Continue = false; // stops the frame
}
// this raises an event listened for by the main window view model,
// displaying the message box and greying out the rest of the program.
base.ShowMessageBox(b);

// This will "block" execution of the current dispatcher frame
// and run our frame until the dialog is closed.
Dispatcher.PushFrame(frame);

Vous pouvez faire votre fonction dans un itérateur qui retourne un IEnumerator<CustomMessageBox>, puis l'écrire comme ceci:

//some code
yield return new CustomMessageBox("hello world");
//some more code

Vous pouvez ensuite écrire une fonction wrapper qui prend le recenseur et appelle MoveNext (qui exécutera toutes les fonctions jusqu'à la prochaine yield return) dans les gestionnaires de DialogClosed.

Notez que la fonction d'emballage ne serait pas un appel de blocage.

Mettre en place une autre boucle de message dans la classe de boîte de message. Quelque chose comme:

public DialogResult ShowModal()
{
  this.Show();

  while (!this.isDisposed)
  {
    Application.DoEvents();
  } 

   return dialogResult;
}

Si vous regardez Windows.Form dans le réflecteur, vous verrez qu'il fait quelque chose comme ça ..

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top