[英]Cannot access a disposed object error
我收到錯誤消息無法訪問已處置的對象。 對象名稱:'ApplicationProperties'。 當我在關閉它之后嘗試重新打開表單時。 我注意到這是從退出表單,並退出是“處置”它們,所以我已將以下代碼放在我的所有接受按鈕,並取消按鈕(任何關閉表單的按鈕)。
this.Hide();
this.Parent = null;
這段代碼只是隱藏了表單。 沒有關閉表格。
所以我的問題是,當我單擊表單上的“x”按鈕,然后嘗試重新打開表單時仍然會收到錯誤消息。 我嘗試了幾種不同的方法來修改表單的現有功能,例如:
private void ApplicationProperties_FormClosing(object sender, FormClosingEventArgs e)
{
//Hiding the window, because closing it makes the window unaccessible.
this.Hide();
this.Parent = null;
}
但這讓我沒有運氣。 我想知道是否有人知道如何解決這個問題。 這是在我的取消和接受按鈕內為我工作的代碼。 關閉表單的所有按鈕都是一樣的。
private void OptionsCancelbtn_Click(object sender, EventArgs e)
{
//Hiding the window, because closing it makes the window unaccessible.
this.Hide();
this.Parent = null;
}
我已經在form1的類頂部聲明了實例,並在form1中有一個打開form2的按鈕。
public partial class MainBox : Form
{
//Making a name for the ApplicationProperties form. It can be opened when called.
ApplicationProperties ApplicationPropertiesWindow = new ApplicationProperties();
private void ApplicationPropertiesbtn_Click(object sender, EventArgs e)
{
//Show the properties window.
ApplicationPropertiesWindow.Show();
}//End ApplicationProperties button.
}
在我使用第二個表單上的“x”按鈕關閉程序后,由於在ApplicationPropertiesWindow.Show();
觸發了錯誤消息,因此無法再次訪問form2 ApplicationPropertiesWindow.Show();
在form2中我有以下代碼:
public partial class ApplicationProperties : Form
{
//Creates and sets the instance MainBoxWindow.
public MainBox MainBoxWindow { get; set; }
在FormClosing
事件中嘗試此FormClosing
:
private void ApplicationProperties_FormClosing(object sender, FormClosingEventArgs e)
{
//Hiding the window, because closing it makes the window unaccessible.
this.Hide();
this.Parent = null;
e.Cancel = true; //hides the form, cancels closing event
}
因為現在它仍在關閉表格,因此仍然導致錯誤。
在我使用第二個表單上的“x”按鈕關閉程序后,由於在
ApplicationPropertiesWindow.Show();
觸發了錯誤消息,因此無法再次訪問form2ApplicationPropertiesWindow.Show();
當窗體關閉( Form.Close
)時,表單本身及其所有相關資源都將被釋放。 如文檔中所述,此自動處理只有兩個例外:
ShowDialog
(而不是Show
)將表單顯示為模式對話框。 它以這種方式設計,以便您可以在用戶關閉對話框后訪問對話框的屬性(例如,檢索用戶輸入)。 在這兩種特殊情況下,您都負責手動調用表單的Dispose
方法。 第二種情況是迄今為止最常見的(沒有人真正使用MDI范例),並且using
語句可以輕松處理:
using (MyDialogBox dlg = new MyDialogBox())
{
DialogResult result = dlg.ShowModal(this);
if (result == DialogResult.Yes)
{
// access members of "dlg", and
// do whatever the user asked
}
} // the Dispose method is automatically called here
在您的情況下,通常情況下,對Close
方法的調用正在關閉並銷毀表單。 您已經知道您無法訪問已處置的對象(因為它不再存在!),因此當您嘗試顯示它時,這就是您獲得異常的原因。 為了在關閉后再次顯示表單,您需要創建表單類的新實例:
MyForm frm = new MyForm();
frm.Show();
// ...
frm.Close();
這確實是最好的方法。 表單的新實例將與您關閉的實例相同,因為它是從同一個類創建的。 您最好開始考慮面向對象的術語,盡可能避免使用基於單件的設計。 屏幕上顯示的每個表單都是一個新的獨立對象 。 一旦該對象被關閉並銷毀,您就不能再使用它了。 如果要再次使用它,則需要創建一個新對象並顯示它。
Hide
方法更像是一個hack,只有當你想要暫時隱藏表單的當前實例同時仍保留其狀態(例如,其成員屬性的值,其控制狀態等)時才有用。 這僅適用於永遠不會被銷毀的單件對象,必須仔細設計和維護。 這也意味着這個表單對象一直消耗資源,無論是否正在使用,這都是浪費。
如果必須這樣做,則需要跟蹤導致表單實例處理的原因。 在沒有看到所有代碼的情況下,我很難做任何事情,但要猜測問題可能在哪里。 它可能與您使用AcceptButton
和/或CancelButton
屬性有關。 無論哪種方式,最好和最干凈的解決方案是覆蓋OnFormClosing
方法並防止您的表單被關閉。 你會隱藏它:
public class MyForm : Form
{
protected virtual void OnFormClosing(FormClosingEventArgs e)
{
// Prevent the form from closing.
e.Cancel = true;
// Hide it instead.
this.Hide();
}
// ...other code in your form class
}
這樣做的好處是,您只需將代碼放在一個位置,在負責類的本地,而不是暴露給外部代碼並分散在整個應用程序中。 當然,它還可以防止表單被控制之外的框架代碼關閉。
我不知道你為什么要將Parent
屬性設置為null
。 頂級窗口(所有表單都是這樣)可以永遠不會有父級。 只有子窗口(例如控件)才有父母。 它可以有一個所有者,但不一定。 這取決於在調用Show
方法時是否將所有者窗口作為參數傳遞。
首先刪除this.Parent = null bcose隱藏表單時不需要這樣做
現在,當您隱藏表單時,如果您仍想在靜態var中訪問此表單存儲表單。 當對象不再使用時,Bcous垃圾收集器處理它並且它將不再可用。
問題,至少可能是其中的一部分,看起來像是階級相互依賴。
初始化ApplicationProperties
實例時,您正在創建對MainBox
對象的引用,但是在MainBox
類的定義中,您正在創建一個引用MainBox
的新ApplicationsProperties
對象....我甚至讓自己感到困惑。 MainBox
是您的父表單,即啟動應用程序時加載的表單嗎?
如果在ApplicationProperites
類中設置對它的引用,那么當MainBox
某些東西被無意中破壞時,我會不會感到驚訝...當你點擊“X”時它會被處置MainBox
。 再次,這是一個有根據的猜測; 我不確定這是不是原因,但即使代碼本身沒有錯 ,它對我來說也很古怪。
如果您希望ApplicationProperties
窗口永遠持續並簡化操作,只需在應用程序持續時間的任何形式的開頭初始化它的靜態實例,並顯示/隱藏它類似於您最初嘗試的內容。 如果你想要高效和基礎,只要你需要讓用戶修改它就構造和處理ApplicationProperties
,但是殺死循環依賴。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.