2009-01-31 16 views
104

Escribo mi primera aplicación en WPF y deseo que el usuario ingrese algunos datos en una ventana de diálogo modal. Aparentemente, esto no es fácil de hacer en WPF, porque la ventana padre permanece completamente habilitada, y el método que creó la nueva ventana secundaria no se detiene y espera a que la ventana secundaria llame a Close(). En cambio, simplemente sigue avanzando. Esto no es lo que quiero.¿Cómo se hace un diálogo modal en WPF?

¿Cómo puedo hacer que se abra la ventana secundaria y que la ventana principal espere a que el hijo se cierre antes de que la ventana principal continúe ejecutándose?

Respuesta

187

¿Intentó mostrar su ventana utilizando el método ShowDialog?

No olvide establecer el Owner property en la ventana de diálogo en la ventana principal. Esto evitará el comportamiento extraño cuando Alt + Tabbing, etc.

+2

estoy aprendiendo, jeje ... Muy bonito, gracias –

+74

No se olvide de establecer la propiedad Owner en la ventana de diálogo. De lo contrario, el usuario obtendrá un comportamiento extraño cuando Alt + Tabbing, etc. –

+3

@EdwardBrey en serio BIG PET PEEVE –

2

Dado un objeto Window myWindow, myWindow.Show() lo abrirá sin moderadamente y myWindow.ShowDialog() lo abrirá de forma modal. Sin embargo, incluso este último no bloquea, por lo que recuerdo.

+6

Creo que bloquea. El código después de myWindow.Show() no se está ejecutando hasta que myWindow llame a Close(). –

24

Window.Show Window mostrará la ventana y continuará la ejecución; es una llamada no bloqueante.

Window.ShowDialog bloqueará el hilo de llamada (un poco [1]) y mostrará el cuadro de diálogo. También bloqueará la interacción con la ventana principal/propietaria. Cuando se cierra el diálogo (por cualquier motivo) ShowDialog regresará a la persona que llama, y ​​le permitirá acceder a DialogResult (si lo desea).

[1] Mantendrá al despachador bombeando al presionar un marco de despacho en el dipatcher de WPF. Esto hará que la bomba de mensajes siga bombeando.

+0

explicar esto con más detalle por favor? Estoy viendo un problema similar en el que tengo un proceso de prueba en ejecución, pero los mensajes de advertencia pueden aparecer como diálogos modales, pero no quiero bloquear la ejecución. – Firoso

13

Muchas de estas respuestas son simplistas, y si alguien está comenzando WPF, es posible que no conozcan todos los "in-and-outs", ya que es más complicado que simplemente decirle a alguien "¡Use .ShowDialog()!". Pero ese es el método (no .Show()) que desea utilizar para bloquear el uso de la ventana subyacente y evitar que el código continúe hasta que se cierre la ventana modal.

En primer lugar, necesita 2 ventanas de WPF. (Una de ellas será llamar a la otra.)

Desde la primera ventana, digamos que se llamaba MainWindow.xaml, en su código subyacente será:

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 
} 

Publique sus botón a su XAML:

<Button Name="btnOpenModal" Click="btnOpenModal_Click" Content="Open Modal" /> 

y haga clic con la rutina Click, seleccione "Ir a definición". Se va a crear para usted en MainWindow.xaml.cs:

private void btnOpenModal_Click(object sender, RoutedEventArgs e) 
{ 
} 

Dentro de esta función, tiene que especificar la otra página utilizando su clase de página. Digamos que usted nombró otra página "ModalWindow", por lo que se convierte en su clase de página y es cómo se instancia (llamada) que:

private void btnOpenModal_Click(object sender, RoutedEventArgs e) 
{ 
    ModalWindow modalWindow = new ModalWindow(); 
    modalWindow.ShowDialog(); 
} 

Digamos que tiene un valor que será necesario que ajuste en su diálogo modal.Crear un cuadro de texto y un botón en el ModalWindow XAML:

<StackPanel Orientation="Horizontal"> 
    <TextBox Name="txtSomeBox" /> 
    <Button Name="btnSaveData" Click="btnSaveData_Click" Content="Save" /> 
</StackPanel> 

A continuación, cree un controlador de eventos (otro Click caso) de nuevo y lo utilizan para guardar el valor del cuadro de texto a una variable estática pública sobre ModalWindow y llame this.Close().

public partial class ModalWindow : Window 
{ 
    public static string myValue = String.Empty;   
    public ModalWindow() 
    { 
     InitializeComponent(); 
    } 

    private void btnSaveData_Click(object sender, RoutedEventArgs e) 
    { 
     myValue = txtSomeBox.Text; 
     this.Close(); 
    } 
} 

Entonces, después de su declaración .ShowDialog(), se puede agarrar ese valor y utilizarlo:

private void btnOpenModal_Click(object sender, RoutedEventArgs e) 
{ 
    ModalWindow modalWindow = new ModalWindow(); 
    modalWindow.ShowDialog(); 

    string valueFromModalTextBox = ModalWindow.myValue; 
} 
+1

Eso no funciona. Tu ModalPage debería extender 'Window' y no' Page'. –

+0

Lo tenía en mi código. Estás en lo correcto. Actualicé mi respuesta. Básicamente estaba tratando de proporcionar una versión desinfectada del código real de mi proyecto, así que sé que este "framework" funciona, pero sí, debería haber tenido 'Window' y no' Page'. Probablemente no tomé mi café esa mañana. – vapcguy

+1

Ahora está bien. Un ejemplo simple y funcional. Gracias. –

Cuestiones relacionadas