Domanda

Sto scrivendo un programma (c # + WPF) dove tutti i dialoghi in stile modali sono implementate come un UserControl sulla cima di una griglia in copre la Window principale. Questo significa che v'è un solo Window e mantiene l'aspetto di tutte le applicazioni imprese.

Per mostrare una MessageBox, la sintassi è la seguente:

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

Come si può vedere, non solo è il flusso di esecuzione in realtà rovesciata, ma la sua terribilmente prolisso rispetto alla versione classica di .NET:

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

Quello che sto veramente cercando è un modo per non tornare dalla base.ShowMessageBox fino a quando la finestra chiusa evento è stato sollevato da esso, ma non posso vedere come sia possibile aspettare per questo senza appendere il filo GUI e impedendo all'utente quindi sempre facendo clic su OK. Sono consapevole che posso prendere una funzione delegato come parametro alla funzione ShowMessageBox quale tipo di impedisce l'inversione di esecuzione, ma provoca ancora qualche folle sintassi / rientro.

Mi sto perdendo qualcosa di ovvio o c'è un modo standard per fare questo?

È stato utile?

Soluzione

Si potrebbe voler dare un'occhiata a questo articolo su CodeProject e < a href = "http://msdn.microsoft.com/en-us/library/aa969773.aspx#Creating_a_Modal_Custom_Dialog_Box" rel = "noreferrer"> questo articolo su MSDN. Il primo articolo ti guida attraverso la creazione manuale di un finestra di dialogo modale blocco, e il secondo articolo viene illustrato come creare finestre di dialogo personalizzate.

Altri suggerimenti

Il modo per farlo è quello di utilizzare un DispatcherFrame oggetto .

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

Si potrebbe fare la vostra funzione in un iteratore che restituisce un IEnumerator<CustomMessageBox>, quindi scrivere in questo modo:

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

Si potrebbe quindi scrivere una funzione wrapper che prende l'enumeratore e chiama MoveNext (che eseguirà tutte le funzioni fino al prossimo yield return) nei gestori DialogClosed.

Si noti che la funzione wrapper non sarebbe una chiamata di blocco.

Imposta un altro ciclo di messaggi nella classe finestra di messaggio. Qualcosa di simile:

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

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

   return dialogResult;
}

Se si guarda alla Windows.Form in Reflector vedrete che fa qualcosa di simile ..

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top