2008-12-19 1987 views
44

我正在處理一個應用程序,該應用程序顯示一些可以由用戶關閉或自動關閉的子窗口。在調試一些正在拋出的異常時,我發現我正試圖在已經關閉的窗口上調用Hide()等方法;這個特殊的代碼分支對兩種情況都是常見的,我沒有注意到這一點。如何判斷WPF窗口是否關閉?

我的第一個想法之一是尋找一個Window上的財產,這表明窗戶已關閉。我似乎無法找到一個。在WinForms中,我希望IsDisposed屬性有一個可靠的指標,表單已被關閉(它不會可靠地用於對話框,但我不用對話框工作)。我沒有看到任何東西相當於WindowWindow.Close()的文檔似乎並未指出由該方法更改的任何屬性。我是否錯過了一些顯而易見的東西,或者是唯一知道窗口是否已關閉以處理事件的方法?對於簡單的任務來說,這似乎是一種苛刻的要求。

回答

45

根據MSDN WPF論壇上的this conversation(請參閱最後一篇文章),您可以檢查IsLoaded是否爲false,這意味着該窗口「適合」卸載其內容。我希望這對你有用!

+4

該屬性不能從另一個線程訪問,並調用一個調用安置在窗口塊無限。所以我最終使用了我自己的實例變量,並以不需要同步的方式訪問它(在OnClosed方法的開始處isClosed = true,然後再次閱讀它)。 – ygoe 2012-02-22 09:17:24

+3

如果事件仍在處理中,這不起作用。例如,如果按鈕單擊處理程序關閉一個窗口,然後打開另一個窗口,並且第二個窗口的初始化檢查第一個「IsLoaded」,它將返回「true」。 – nmclean 2014-02-26 16:16:29

7

另一種方式:Application.Windows包含打開的窗口列表。 你可以檢查這個集合是否包含你的窗口(它在關閉後被刪除)。

看起來你必須致電OfType<Window>(),因爲它是一個專門的集合。

+3

要小心這個 - 這可能有時包含沒有關閉的窗口,尤其是那些由於XAML – 2012-03-30 21:50:38

3

希望這可幫助您:

PresentationSource.FromVisual(window)== null;

3

我不知道爲什麼IsDisposed性質是內部的,但如果你不害怕反思:

var window = new Window(); 
var propertyInfo = typeof(Window).GetProperty("IsDisposed", BindingFlags.NonPublic | BindingFlags.Instance); 
var isDisposed = (bool)propertyInfo.GetValue(window); 

話雖這麼說,反思是不是被過度使用,因爲你不再受該類的公共API保護。如果你走這條路線,一定要至少使用單元測試。

4

我的解決辦法是簡單的事件附加到對話框的Closed事件:

MikesDialog dlg = new MikesDialog(); 
dlg.Closed += delegate 
{ 
    // The user has closed our dialog. 
    validationgDlg = null; 
}; 

// ...elsewhere in the code... 

if (validationgDlg != null) 
{ 
    // Our "MikesDialog" is still open... 
    . . . 
} 
4

如果你從Window類派生的,你可以這樣做:

public bool IsClosed { get; private set; } 

protected override void OnClosed(EventArgs e) 
{ 
    base.OnClosed(e); 
    IsClosed = true; 
} 

它在有優勢註冊Closed事件 - 無需取消註冊回調。

0

您可以在非靜態的屬性添加到WindowClass bool IsClosed,並在Closed事件設置爲true:

public partial class MyWindow : Window 
{ 
    public bool IsClosed { get; set; } = false; 
    public MyWindow() 
    { 
     Closed += MyWindow_Closed; 
     InitializeComponent(); 
    } 
}  

private void MyWindow_Closed(object sender, EventArgs e) 
{ 
    IsClosed = true; 
}