2012-11-03 7 views
11

Ho notato questo comportamento molto strano in un'applicazione WPF.La finestra principale scompare dietro le finestre di altre applicazioni dopo che una finestra secondaria utilizza ShowDialog su una terza finestra

Ho un MainWindow, che viene visualizzato utilizzando Show() da App.OnStartup. Detto MainWindow può aprire un (non modale) SubWindow, anche utilizzando Show(). OwnerSubWindow è impostato su MainWindow.

Quando SubWindow è chiuso, MainWindow è di nuovo visibile (buono).

Alcune azioni possono causare il SubWindow per aprire una terza finestra come finestra di dialogo modale, utilizzando ShowDialog() (Owner è impostato su SubWindow). Quando quella finestra di dialogo modale viene aperta e chiusa almeno una volta durante la vita di uno SubWindow, la cosa strana accade.

Dopo la chiusura SubWindow, MainWindow non viene visualizzato. Invece, qualsiasi finestra casuale è dietroMainWindow viene visualizzata. Qualcuno può spiegarmi perché questo accade e come risolverlo?

Non fa alcuna differenza se la finestra di dialogo modale è una normale Window visualizzata utilizzando ShowDialog() o una finestra di messaggio visualizzata utilizzando MessageBox.Show().


Ecco il codice minimo di riprodurre questo. Creare una nuova applicazione WPF in Visual Studio e incollarla nel MainWindow.xaml.cs pre-generato.

Quindi, premere un tasto sulla tastiera per aprire solo una finestra, chiuderla, comportarsi come previsto. Premi due tasti, chiudi entrambi, quindi la prima finestra è dietro a Visual Studio (presumibilmente).

public MainWindow() 
{ 
    InitializeComponent(); 
    this.PreviewKeyDown += (sender, e) => 
    { 
     if (this.Owner is MainWindow) 
     { 
      // we're the SubWindow 

      MessageBox.Show("I am a modal dialog"); 

      // code below produces the exact same behavior as the message box 

      //var dialog = new MainWindow(); 
      //dialog.Owner = this; 
      //dialog.ShowDialog(); 
     } 
     else 
     { 
      // we're the initial MainWindow created by App. 
      var subWindow = new MainWindow(); 
      subWindow.Owner = this; 
      subWindow.Show(); 
     } 
    }; 
} 

risposta

9

questo un bug piuttosto fastidioso WPF, non ho mai fatto trovare la falla nel codice che causa, ma c'è un heckofalot di "devo capire questo" commenti nel codice sorgente che si occupa di messa a fuoco. Solo una soluzione alternativa, meno che ideale, è possibile risolverlo dando esplicitamente l'attenzione al proprietario quando la finestra si sta chiudendo. Copia/incolla questo codice nella tua classe SubWindow;

protected override void OnClosing(System.ComponentModel.CancelEventArgs e) { 
     base.OnClosing(e); 
     if (!e.Cancel && this.Owner != null) this.Owner.Focus(); 
    } 
+1

Per quel che vale abbiamo visto questo bug in WinForms pianura (NET 2) applicazione ho lavorato su circa 5 anni fa. Ho appena eseguito di nuovo oggi in un nuovo progetto (.NET 4.5). Mi sembra di ricordare che l'errore dipende dall'avere 'Show()' nidificato a 2 profondità o altro. Sembra che anche altre persone vi si siano imbattuti ([qui] (http://www.pcreview.co.uk/forums/vbulletin-2005-windows-app-goes-back-z-order-after-dialog-box- clo-t3140486.html) e [qui] (http://web1.codeproject.com/Messages/1813163/Application-Goes-to-Back-of-ZOrder-after-cloasing-.aspx)); se ricordo che abbiamo usato una soluzione come suggerisce @Hans. –

+0

Giusto per farti sapere, il tuo codice causa un ciclo infinito. Posso solo immaginare che 'base.OnClosing' è una funzione virtuale che è implementata nel metodo che stai chiamando, quindi chiama se stessa. – Steztric

+0

Un'altra cosa, gestire l'evento 'Closing' non risolve il problema per me - ho avuto bisogno di gestire l'evento' Closed'. – Steztric

0

Colpire lo stesso problema solo nascondendo la finestra. Non riesco a vedere che c'è un evento equivale a chiusura in questa situazione, ma in ogni caso questo funziona:

 if (Owner != null) Owner.Focus(); 
     Hide(); 
Problemi correlati