2009-05-22 4 views
26

mi mostra una finestra WPF utilizzando ShowDialog() dalla finestra chiamante. La finestra si apre ed è modale come previsto. Tuttavia, negli eventi di clic del pulsante OK e Annulla nella finestra di dialogo ho impostato rispettivamente questo.DialogResult = true (o false) e il valore non viene impostato. La finestra si chiude come previsto, ma DialogResult è ancora nullo.Impossibile impostare DialogResult in WPF

Si tratta di un bug in WPF? O c'è un motivo per cui la proprietà DialogResult non può essere impostata ancora non genera un'eccezione? La finestra non è ospitata in un browser.

codice nella finestra di chiamare:

Window2 win = new Window2(); 
bool? result = win.ShowDialog(); 
if (result.HasValue && result.Value) { 
    //never gets here because result is always null 
} 

codice nella finestra di dialogo: (? Bool)

this.DialogResult = true; 
+0

Come si imposta DialogResult su un valore bool? Dovrebbe essere un enum, come DialogResult.OK – Brandon

+12

No, in WPF, se apri un oggetto Window con il suo metodo ShowDialog(), puoi impostare DialogResult su un valore booleano. – Carlo

+0

Aggiunto codice per rispondere allo – Carlo

risposta

9

Ben prima di tutto si deve prendere in considerazione che restituisce un bool annullabile , così al fine di confrontarlo o impostarlo su un'altra variabile bisogna lanciare ad un bool regolare

bool result = (bool)myWindow.DialogResult; 

a s perché è nullo ... Non vedo perché dovrebbe accadere, a meno che non sia in qualche modo ripristinato a null DOPO essere impostato su vero o falso. Puoi mostrare il tuo codice?

EDIT:

Il codice ha funzionato bene per me, questo è quello che ho nella seconda finestra:

private void button2_Click(object sender, RoutedEventArgs e) 
{ 
    this.DialogResult = false; 
} 

private void button1_Click(object sender, RoutedEventArgs e) 
{ 
    this.DialogResult = true; 
} 

E in Window1:

private void window1_Loaded(object sender, RoutedEventArgs e) 
{ 
    Window2 win = new Window2(); 

    bool? result = win.ShowDialog(); 

    if (result.HasValue && result.Value) 
    { 
     //it DID get here 
    } 
} 

C'è grande differenza ?

+2

In una sessione di debug, controllo immediatamente il valore di DialogResult dopo averlo impostato su true ed è ancora nullo. – quinnapi

+0

Hhmmm, puoi pubblicare il tuo codice? – Carlo

+0

Nessuna differenza. In effetti, faccio la stessa identica cosa con molte altre finestre nello stesso progetto, e funzionano tutte bene. – quinnapi

18

DialogResult è un bool annullabile. Tuttavia non devi lanciarlo per ottenere il suo valore.

bool? result = myWindow.ShowDialog(); 
if (result ?? false) 
{ 
    // snip 
} 

Il ?? imposta il valore predefinito da restituire se il risultato è nullo. Ulteriori informazioni: Using Nullable Types (C# Programming Guide)

Per quanto riguarda la domanda originale, l'unica volta che ho visto e rintracciato questo problema è quando la finestra veniva disposta tra l'impostazione del DialogResult e la chiusura della finestra. Sfortunatamente, l'unico consiglio che posso offrire è che passi attraverso il tuo codice e controlli l'ordine delle operazioni. Credo di averlo "corretto" impostando lo DialogResult e quindi chiudendo esplicitamente la finestra.

+0

La finestra non viene eliminata in quel momento. – quinnapi

+0

giusto. Un mio amico usa result.Value per ottenere vero o falso. –

+4

Preferisco 'risultato == vero'. Penso che sia più leggibile, dovrei pensare a cosa ??'fa qui. – svick

2

fare si chiude la finestra prima u impostare il DialogResult? Dovresti pubblicare l'intero contenuto dei tuoi gestori di eventi pulsante.

+0

Penso che sia giusto. L'unico modo in cui risolveremo questo è vedere più contesto. – PeterAllenWebb

6

Ho appena avuto esattamente lo stesso problema e sembra essere causato dal mio sovrascrivere il metodo OnClosing(). Avevo bisogno di sovrascrivere OnClosing() per fermare l'utente che chiude la finestra modale tramite il pulsante di chiusura (X).

Quando io commento il metodo OnClosing(), il problema va via e il DialogResult viene restituito con i valori attesi di vero o falso, come set.

Per interesse qui è stato il mio scatto del tasto i gestori e il metodo OnClosing:

private void AlternateButton_Click(object sender, RoutedEventArgs e) 
{ 
    this.DialogResult = false; 
    buttonHasBeenClicked = true; 
    this.Close(); 
} 

private void DefaultButton_Click(object sender, RoutedEventArgs e) 
{ 
    this.DialogResult = true; 
    buttonHasBeenClicked = true; 
    this.Close(); 
} 

protected override void OnClosing(System.ComponentModel.CancelEventArgs e) 
{ 
    base.OnClosing(e); 
    if (!buttonHasBeenClicked) 
    { 
     // Prevent the user closing the window without pressing one of the buttons. 
     e.Cancel = true; 
    } 
} 
+0

Come seguito, ho appena rimosso il pulsante di chiusura (x) dalla finestra in modo che non debba più eseguire l'override di OnClosing(). Maggiori informazioni qui: http://stackoverflow.com/questions/743906/how-to-hide-close-button-in-wpf-window –

+0

Anche se il pulsante close (x) è nascosto, l'utente potrebbe comunque chiudere la finestra premendo Alt-F4 o facendo clic su un pulsante la cui proprietà "IsCancel" è impostata su "True". –

+0

Ho avuto un problema simile. Il tuo post ha aiutato! Grazie! – al2suarez

3

Sono stato in questo problema troppo, e l'unico modo che ho trovato per risolvere il problema stava usando questo codice nella mia classe:

public new bool? DialogResult { get; set; } 

e dopo aver impostato il mio DialogResult funziona per me !! (molto strano problema). questo era il codice stavo usando:

cmdCancel = new RelayCommand(() => { DataContact.Reload(); this.DialogResult = false; this.Close(); }); 

e ad aprire la mia finestra:

public static MessageBoxResult ShowQuestionYesNo(string message) 
     { 
      POLMessageBox w = new POLMessageBox("سوال", MessageBoxType.QuestionYesNo, message); 
      w.ShowDialog(); 
      var b = w.DialogResult; 
      if (b == true) return MessageBoxResult.Yes; 
      if (b == false) return MessageBoxResult.No; 
      return MessageBoxResult.No; 
     } 
+0

Dopo aver esaminato diverse di queste risposte, questo è quello che ho fatto anch'io. È brutto e richiede documentazione e commenti, ma è l'unico modo per evitare di farmi muovere le dita da WPF. – Grault

0

Ho appena incontrato il problema troppo. Risulta che ho impostato DialogResult all'interno di una coppia di istruzioni IF e per questo motivo (per quanto strano possa sembrare) ha causato l'errore. Non appena questa singola riga è stata rimossa, il problema è stato risolto.

private void OKButton_Click(object sender, RoutedEventArgs e) 
    { 
     if (!string.IsNullOrEmpty(startBlockPosBox.Text)) 
     { 
      .. do stuff .. 
     } 
     else 
     { 
      .. do stuff .. 
      DialogResult = true; // this line caused the problem 
     } 

     DialogResult = true; 
    } 
0

Ho il seguente nella pagina della finestra di dialogo. (dialogwindow.xaml.cs)

private void dlgWindowYesButton_Click(object sender, RoutedEventArgs e) 
    { 
     this.DialogResult = true; 
     this.Close(); 
    } 

    private void dlgWindowNoButton_Click(object sender, RoutedEventArgs e) 
    { 
     this.DialogResult = false; 
     this.Close(); 
    } 

Nella pagina chiamante ho usato il dialogwindow in questo modo:

dialogwindow dWinObj = new dialogwindow(); 
if(dWinObj.ShowDialog().Value == true) 
{ 
    //perform the operation when the user clicks "Yes" 
} 
-1

ho avuto un problema simile, ma il mio problema è venuto dal codice all'interno mia dichiarazione di chiusura. Stavo cercando di eliminare() una lista prima che la finestra si chiudesse e quindi impostare la proprietà List < su null ... stava soffocando sulla proprietà set quando stavo tentando di impostare il suo valore su null, quindi mi è venuto in mente Seguendo maldestra soluzione nel mio metodo di proprietà set e tutto ha funzionato in seguito:

List<SettingItem> settingItems; 
    public IEnumerable<SettingItem> Settings 
    { 
     get 
     { 
      return settingItems.OrderBy(t => t.Name).AsEnumerable(); 
     } 
     set 
     { 
      if (value == null) 
      { 
       settingItems.Clear(); 
      } 
      else 
      { 
       settingItems = value.ToList(); 
      } 
     } 
    }