2010-11-14 4 views
7

Dans WPF vous appelez ShowDialog sur une fenêtre exactement une fois. Après cela, c'est fait pour.Comment détecter qu'une fenêtre a utilisé son appel "ShowDialog"

Semble un peu boiteux pour moi, mais ce sont les règles. Si vous appelez ShowDialog à nouveau, vous obtenez cette exception:

ne peut pas définir la visibilité ou appelez Show, ShowDialog ou WindowInteropHelper.EnsureHandle après une fenêtre a fermé

Ce que je veux savoir est: Comment puis-je Prenez un Window (ou UserControl vraiment) et vérifiez s'il a eu ShowDialog appelé (donc je sais à new jusqu'à un autre différent avant d'appeler à nouveau ShowDialog).

Quelque chose comme ceci:

public void ShowListOfClients() 
{ 
    // | This is the method I want to write 
    // V           
    RefreshViewIfNeeded(_myWindowOrUserControlThatShowsAList); 

    FillWindowWithBusinessData(_myWindowOrUserControlThatShowsAList); 
    _myWindowOrUserControlThatShowsAList.ShowDialog(); 

} 

NOTE: Il est clair que dans l'exemple ci-dessus, il serait plus facile de créer un nouveau WindowOrUserControlThatShowsAList chaque fois que je rentre dans la méthode. Mais s'il vous plaît considérez la question plus que l'exemple délabré.

Répondre

9

Ceci n'est pas exclusif à ShowDialog(), Show() le fait aussi. Et non, il n'y a pas de propriété IsDisposed à vérifier. IsLoaded n'est qu'une demi-solution, elle sera également fausse pour la première invocation.

Première approche est de simplement faire une boîte de dialogue qui peut être re-montré:

public bool CloseAllowed { get; set; } 

    private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) { 
     if (!CloseAllowed) { 
      this.Visibility = System.Windows.Visibility.Hidden; 
      e.Cancel = true; 
     } 
    } 

Le prochain est de garder explicitement trace de la santé de la référence d'objet:

private Window1 win = new Window1(); // say 

    private void button1_Click(object sender, RoutedEventArgs e) { 
     if (win == null) { 
      win = new Window1(); 
      win.Closing += delegate { win = null; }; 
     } 
     win.ShowDialog(); 
    } 
+0

J'ai fouillé le dernier. Je ne peux pas penser à un // dire fix. –

+0

J'aime le délégué à la méthode de fermeture. Ça à l'air bon. Merci! – Vaccano

+0

Sauf que la première suggestion ci-dessus ne fonctionne pas spécifiquement pour les fenêtres modales, c'est-à-dire avec ShowDialog() '. Cela évitera l'exception, mais cela provoque d'autres problèmes, comme ne pas pouvoir quitter le processus, et ne pas afficher correctement la fenêtre la deuxième fois qu'elle est rendue visible. Seule la seconde suggestion (c'est-à-dire recréant toujours la fenêtre) est viable. –

3

Eh bien la sale façon de le faire serait d'attraper l'exception.

La manière propre de le faire serait d'afficher une fenêtre avec ShowDialog, et détruire (perdre la référence à, etc) la fenêtre lorsque la fonction retourne. La vue ne doit pas être étroitement liée aux modèles (vous utilisez MVVM à droite?). La création de nouveaux objets visuels pour chaque vue client ne devrait donc pas poser de problème.

+0

J'utilise MVVM, mais si je fais ce que vous suggérez alors j'ai mon modèle créant la vue qu'il supporte (quelque chose que l'on me dit que le MVVM fronce les sourcils). – Vaccano

+0

Si un modèle doit être mis à jour à l'écran, il doit déclencher un événement. Cet événement peut être attaché à une vue. Cette vue peut être la fenêtre du propriétaire, qui renvoie la vue réelle à une boîte de dialogue séparée. – Guy

0

facile façon de traiter ce problème sans gâcher avec l'événement de clôture:

public partial class MainWindow 
{ 
    private SomeCustomWindow _someCustomWindow; 

    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void OnOpenCustomWindowButtonClick(object sender, RoutedEventArgs e) 
    { 
     if (_someCustomWindow != null) 
      _someCustomWindow.Close(); 
     _someCustomWindow = new SomeCustomWindow(); 

     _someCustomWindow.ShowDialog(); 
    } 

    private void OnWindowClosing(object sender, CancelEventArgs e) 
    { 
     if (_someCustomWindow!= null) 
      _someCustomWindow.Close(); 
    } 
} 
Questions connexes