2010-11-14 15 views
7

W WPF, możesz wywołać ShowDialog w oknie dokładnie jeden raz. Po tym jest zrobione.Jak wykryć, że okno zużyło swoje wywołanie "ShowDialog"

Wydaje mi się, że to kiepski, ale takie są zasady. Jeśli zadzwonisz ShowDialog znowu pojawi się ten wyjątek:

Nie można ustawić widoczność lub zadzwonić Show, ShowDialog lub WindowInteropHelper.EnsureHandle po zamknięciu okna

Co chcę wiedzieć: jak mogę weź naprawdę Window (lub UserControl) i sprawdź, czy został wywołany ShowDialog (więc wiem, że do new w górę inny przed ponownym wywołaniem ShowDialog).

coś takiego:

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

    FillWindowWithBusinessData(_myWindowOrUserControlThatShowsAList); 
    _myWindowOrUserControlThatShowsAList.ShowDialog(); 

} 

UWAGA: Oczywiście w powyższym przykładzie byłoby łatwiej po prostu stworzyć nową WindowOrUserControlThatShowsAList każdym razem wprowadzić metodę. Ale proszę rozważyć pytanie bardziej niż na przykład.

Odpowiedz

9

Nie dotyczy to tylko ShowDialog(), Show() też. I nie, nie ma właściwości IsDisposed do sprawdzenia. IsLoaded jest tylko pół rozwiązaniem, to będzie również fałszywe dla pierwszej inwokacji.

Pierwsze podejście jest po prostu zrobić okno, które mogą być ponownie pokazany:

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; 
     } 
    } 

Kolejnym z nich jest wyraźnie śledzić zdrowia odniesienia obiektu:

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

Grzebałem ostatni. Nie można wymyślić poprawki // say. –

+0

Lubię delegata do metody zamykania. To wygląda dobrze. Dzięki! – Vaccano

+0

Poza tym pierwsza sugestia powyżej specjalnie nie działa dla okien modalnych, tj. Z 'ShowDialog()'. Pozwoli to uniknąć wyjątku, ale spowoduje inne problemy, takie jak brak możliwości wyjścia z procesu, i niepoprawne wyświetlanie okna po raz drugi, gdy jest on widoczny. Tylko druga sugestia (tj. Zawsze odtworzenie okna) jest możliwa. –

3

Cóż, brudnym sposobem na zrobienie tego byłoby złapanie wyjątku.

Sprytnym sposobem na zrobienie tego byłoby wyświetlenie okna z ShowDialog i zniszczenie (utracenie odniesienia do itp.) Okna po powrocie funkcji. Widok nie powinien być ściśle powiązany z modelami (korzystasz z MVVM, prawda?), Więc tworzenie nowych obiektów wizualnych dla każdego widoku klienta nie powinno stanowić problemu.

+0

Używam MVVM, ale jeśli zrobię to, co sugerujesz wtedy mam swój Model, który tworzy widok, który obsługuje (coś, o czym mówiono MVVM marszczy brwi). – Vaccano

+0

Jeśli model wymaga aktualizacji na ekranie, powinien wystrzelić zdarzenie. Do tego wydarzenia można dołączyć widok. Ten widok może być oknem właściciela, które powoduje, że rzeczywiste oglądanie odbywa się w oddzielnym oknie dialogowym. – Guy

0

Łatwy sposób radzenia sobie z tym problemem bez kłopotów z wydarzeniem Zamknięcie:

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(); 
    } 
} 
Powiązane problemy