2009-01-31 16 views
104

Sto scrivendo la mia prima applicazione in WPF e desidero che l'utente inserisca alcuni dati in una finestra di dialogo modale. Apparentemente, questo non è semplice da fare in WPF, perché la finestra genitore rimane completamente abilitata, e il metodo che ha creato la nuova finestra figlio non si ferma e aspetta che la finestra figlio chiami Close(). Invece continua semplicemente ad andare avanti. Questo non è quello che voglio.Come creare una finestra di dialogo modale in WPF?

Come posso aprire la finestra secondaria e fare in modo che la finestra padre attenda che il bambino si chiuda prima che la finestra padre continui a essere eseguita?

risposta

187

Hai provato a mostrare la tua finestra utilizzando il metodo ShowDialog?

Non dimenticare di impostare Owner property nella finestra di dialogo nella finestra principale. Ciò eviterà comportamenti strani quando Alt + Tab, ecc.

+2

Sto imparando, hehe ... Molto bello, grazie –

+74

non dimenticate di impostare la proprietà Owner nella finestra di dialogo. Altrimenti, l'utente avrà un comportamento strano quando Alt + Tabbing, ecc. –

+3

@EdwardBrey seriamente BIG PET PEEVE –

2

Dato un oggetto Window myWindow, myWindow.Show() lo aprirà in modo non modale e myWindow.ShowDialog() lo aprirà modalmente. Tuttavia, anche quest'ultimo non blocca, da quello che ricordo.

+6

Credo che blocchi. Codice dopo myWindow.Show() non è in esecuzione fino a dopo myWindow chiama Close(). –

24

Window.Show Window mostra la finestra e continua l'esecuzione: è una chiamata non bloccante.

Window.ShowDialog bloccherà il thread chiamante (tipo [1]) e mostrerà la finestra di dialogo. Bloccherà anche l'interazione con la finestra genitore/proprietario. Quando la finestra di dialogo viene chiusa (per qualsiasi motivo) ShowDialog tornerà al chiamante e ti consentirà di accedere a DialogResult (se lo desideri).

[1] Manterrà il pompaggio del dispatcher spingendo un telaio del dispatcher sul dipatcher WPF. Ciò causerà il pompaggio del messaggio alla pompa.

+0

spiegare questo in modo più dettagliato per favore? Sto osservando un problema simile in cui ho un processo di test in esecuzione ma i messaggi di avviso possono apparire come finestre di dialogo modali ma non voglio bloccare l'esecuzione. – Firoso

13

Molte di queste risposte sono semplicistiche, e se qualcuno sta iniziando WPF, potrebbe non conoscere tutti i "in-out", in quanto è più complicato che dire a qualcuno "Usa .ShowDialog()!". Ma questo è il metodo (non .Show()) che si desidera utilizzare per bloccare l'uso della finestra sottostante e per impedire che il codice continui fino alla chiusura della finestra modale.

Innanzitutto, sono necessarie 2 finestre WPF. (Uno sarà chiamando l'altro.)

Dalla prima finestra, diciamo che è stato chiamato MainWindow.xaml, nella sua code-behind sarà:

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

Quindi aggiungere il pulsante al tuo XAML:

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

e fare clic con il Click di routine, selezionare "Vai a definizione". Si creerà per voi in MainWindow.xaml.cs:

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

all'interno di tale funzione, è necessario specificare l'altra pagina utilizzando la sua classe di pagina. Diciamo che con nome che altra pagina "finestra modale", in modo che diventa sua classe pagina ed è come si dovrebbe istanziare (chiamata) è:

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

Diciamo che avete un valore necessario impostare sulla vostra finestra di dialogo modale.Creare una casella di testo e un pulsante nella ModalWindow XAML:

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

Poi creare un gestore di eventi (un altro evento Click) di nuovo e usarlo per salvare il valore casella di testo per una variabile statica pubblica su ModalWindow e chiamare 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(); 
    } 
} 

Poi, dopo la vostra .ShowDialog() dichiarazione, si può afferrare quel valore e usarlo:

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

    string valueFromModalTextBox = ModalWindow.myValue; 
} 
+1

Che non funziona. La tua ModalPage dovrebbe estendere 'Window' e non' Page'. –

+0

Ho avuto ragione nel mio codice. Hai ragione. Ho aggiornato la mia risposta. Fondamentalmente stavo cercando di fornire una versione disinfettata del codice reale del mio progetto, quindi so che questo "framework" funziona, ma sì, avrei dovuto avere 'Window' e non' Page'. Probabilmente non ho preso il caffè quella mattina. – vapcguy

+1

Ora va bene. Un esempio semplice e funzionale. Grazie. –

Problemi correlati