2013-04-24 12 views
25

Woher weiß ich in einem WPF-Fenster, ob es geöffnet ist?Woher weiß ich, ob ein WPF-Fenster geöffnet ist?

Mein Ziel, nur 1 Instanz des Fensters zu der Zeit zu öffnen.

Also, mein Pseudo-Code in dem übergeordneten Fenster ist:

if (this.m_myWindow != null) 
{ 
    if (this.m_myWindow.ISOPENED) return; 
} 

this.m_myWindow = new MyWindow(); 
this.m_myWindow.Show(); 

EDIT:

ich eine Lösung gefunden, die mein erstes Problem löst. window.ShowDialog();

Es blockiert den Benutzer von jedem anderen Fenster zu öffnen, wie ein modales Popup. Mit diesem Befehl muss nicht überprüft werden, ob das Fenster bereits geöffnet ist.

+1

Dank für das Update! window.ShowDialog() ist genau das, was ich brauchte! –

Antwort

60

In WPF gibt es eine Sammlung der offenen Windows in der Application Klasse, können Sie eine Hilfsmethode machen könnten Überprüfen Sie, ob das Fenster geöffnet ist.

Hier ist ein Beispiel, das prüfen wird, ob Window eines bestimmten Type oder wenn ein Window mit einem bestimmten Namen offen ist, oder beides.

public static bool IsWindowOpen<T>(string name = "") where T : Window 
{ 
    return string.IsNullOrEmpty(name) 
     ? Application.Current.Windows.OfType<T>().Any() 
     : Application.Current.Windows.OfType<T>().Any(w => w.Name.Equals(name)); 
} 

Verbrauch:

if (Helpers.IsWindowOpen<Window>("MyWindowName")) 
{ 
    // MyWindowName is open 
} 

if (Helpers.IsWindowOpen<MyCustomWindowType>()) 
{ 
    // There is a MyCustomWindowType window open 
} 

if (Helpers.IsWindowOpen<MyCustomWindowType>("CustomWindowName")) 
{ 
    // There is a MyCustomWindowType window named CustomWindowName open 
} 
+0

Es ist eine gute Lösung! Vielen Dank. Aber da ich einen anderen Weg gefunden habe, mein Problem zu lösen, werde ich es nicht benutzen. – guilhermecgs

+0

@guilhermecgs Welchen einfacheren Weg haben Sie gefunden, um Ihr Problem zu lösen? – estebro

+1

@estebro - Ich habe ein modales Popup verwendet. Meine Anforderung war, Benutzerinteraktion mit anderen geöffneten Fenstern zu vermeiden. Also, ein modales Popup macht das per definitionem. http://stackoverflow.com/questions/499294/how-do-make-modal-dialog-in-wpf – guilhermecgs

8

Sie können überprüfen, ob m_myWindow==null und nur dann Fenster erstellen und anzeigen. Wenn das Fenster geschlossen wird, setzen Sie die Variable auf null zurück.

if (this.m_myWindow == null) 
    { 
      this.m_myWindow = new MyWindow(); 
      this.m_myWindow.Closed += (sender, args) => this.m_myWindow = null;   
      this.m_myWindow.Show(); 
    } 
+0

Ähnliche Lösung zu @ofstream – guilhermecgs

+0

Nur aus Interesse, gibt es einen Speicherverlust in diesem Code, wie wir nie den geschlossenen Event-Handler entfernen oder das Setzen des Objekts auf Null entfernen alle Event-Handler? – user1

+0

@ user1 Ich weiß, das ist alt, aber ja; Ja, es schafft Speicherleck. Ich versuche gerade, einen Weg zu finden, das Problem des Speicherverlusts in einer Behälteranwendung zu lösen, die verschiedene Fenster hervorbringt und sie auf einer Variablen synchronisiert. – JoshHetland

1

Setzen Sie eine statische bool in Ihrer Klasse, mit dem Namen _open oder so ähnlich. Im Konstruktor dann wie folgt vorgehen:

if (_open) 
{ 
    throw new InvalidOperationException("Window already open"); 
} 
_open = true; 

und im Geschlossenen Veranstaltung:

_open = false; 
+3

Es wird funktionieren, aber ich denke, es ist keine "saubere" Lösung. – guilhermecgs

0

Ist das Sie suchen?

if (this.m_myWindow != null) 
{ 
    if (this.m_myWindow.IsActive) return; 
} 

this.m_myWindow = new MyWindow(); 
this.m_myWindow.Show(); 

Wenn Sie einen Singleton wollen, sollten Sie dies lesen: How can we create a Singleton Instance for a Window?

+1

Hallo, IsActive-Eigenschaft funktioniert nicht. Ich denke es überprüft nur, ob das Fenster darauf fokussiert ist (ich bin mir nicht sicher) – guilhermecgs

2

Wenn Sie das Fenster aktivieren müssen, wenn es gefunden wird, können Sie den Code unten verwenden:

//activate a window found 
//T = Window 

Window wnd = Application.Current.Windows.OfType<T>().Where(w => w.Name.Equals(nome)).FirstOrDefault(); 
wnd.Activate(); 
0
void pencereac<T> (int Ops) where T : Window , new() 
    { 
     if (!Application.Current.Windows.OfType<T>().Any()) // Check is Not Open, Open it. 
     { 
      var wind = new T(); 
      switch (Ops) 
      { 
       case 1: 
        wind.ShowDialog(); 
        break; 
       case 0: 
        wind.Show(); 
        break; 
      } 
     } 
     else Application.Current.Windows.OfType<T>().First().Activate(); // Is Open Activate it. 
    } 

kullanımı:

void Button_1_Click(object sender, RoutedEventArgs e) 
{ 
    pencereac<YourWindow>(1); 
} 
0

Hier ist eine andere Möglichkeit, dies mit LINQ zu erreichen.

using System.Linq; 

... 

public static bool IsOpen(this Window window) 
{ 
    return Application.Current.Windows.Cast<Window>().Any(x => x == window); 
} 

Verbrauch:

bool isOpen = myWindow.IsOpen(); 
Verwandte Themen