2009-12-01 14 views
5

Estoy escribiendo una aplicación (C# + wpf) donde todos los cuadros de diálogo de estilo modal se implementan como UserControl en la parte superior de una cuadrícula translúcida que cubre el Window principal. Esto significa que solo hay un Window y mantiene la apariencia de todas las aplicaciones de la empresa.Emulando la funcionalidad de ShowDialog

mostrar un MessageBox, la sintaxis es la siguiente:

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

Como se puede ver, no sólo es el flujo de ejecución realidad invertida, pero su horrible detallado en comparación con la versión clásica .NET:

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

lo que realmente estoy buscando es una manera de no volver a base.ShowMessageBox hasta que el evento cerrado de diálogo ha sido planteada por él, pero no puedo ver cómo es posible esperar a que este sin colgar el hilo GUI y por lo tanto evitando que nosotros siempre haciendo clic en Aceptar. Soy consciente de que puedo tomar una función de delegado como un parámetro para la función ShowMessageBox que impide la inversión de la ejecución, pero aún causa una sintaxis/sangría loca.

¿Me falta algo obvio o hay una forma estándar de hacerlo?

Respuesta

5

Es posible que desee echar un vistazo al artículo this en CodeProject y this artículo en MSDN. El primer artículo lo guiará a través de la creación manual de un diálogo modal de bloqueo, y el segundo artículo ilustra cómo crear diálogos personalizados.

+0

El primer artículo vinculado muestra un ejemplo perfecto de cómo hacerlo. – Guy

0

Se podría hacer su función en un iterador que devuelve un IEnumerator<CustomMessageBox>, a continuación, escribir así:

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

A continuación, escribir una función de contenedor que lleva el empadronador y llama MoveNext (que ejecutará todos la función hasta el siguiente yield return) en los controladores DialogClosed.

Tenga en cuenta que la función de envoltura no sería una llamada de bloqueo.

0

Configure otro bucle de mensaje en la clase de cuadro de mensaje. Algo así como:

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

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

    return dialogResult; 
} 

Si nos fijamos en Windows.Form en Reflector verá que hace algo como esto ..

+0

Está usando WPF, no WinForms. – SLaks

+0

Ah, me lo perdí. WPF es completamente diferente? ¿Windows ya no tiene bucles de mensajes? –

4

La manera de hacer esto es mediante el uso de un objeto DispatcherFrame.

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