我收到错误消息无法访问已处置的对象。 对象名称:'ApplicationProperties'。当我在关闭它后尝试重新打开表单时。我注意到这是来自退出表单,退出是“Disposing”,所以我将以下代码放在我的所有接受按钮中,并取消按钮(任何关闭表单的按钮)
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中我有以下代码:
public partial class ApplicationProperties : Form
{
//Creates and sets the instance MainBoxWindow.
public MainBox MainBoxWindow { get; set; }
答案 0 :(得分:6)
在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
}
因为现在它仍在关闭表单,因此仍然会导致错误。
答案 1 :(得分:4)
我用第二张表格上的'x'按钮关闭程序后 由于触发错误消息,无法再次访问form2
ApplicationPropertiesWindow.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
方法更像是一种黑客攻击,只有当你想暂时隐藏表单的当前实例同时仍保留其状态(例如,其成员属性的值,其控制状态等)时才有用。 )。这仅适用于永远不会被销毁的单件对象,必须仔细设计和维护。这也意味着这个表单对象一直消耗资源,无论是否被使用,都是浪费。
如果必须执行此操作,则需要跟踪导致表单实例处理的原因。在没有看到所有代码的情况下,我很难做任何事情,但要猜测问题可能在哪里。这可能与您使用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
方法时是否将所有者窗口作为参数传递。
答案 2 :(得分:3)
首先删除this.Parent = null bcose隐藏表单
时不需要这样做现在,当您隐藏表单时,如果您仍想在静态var中访问此表单存储表单。当对象不再使用时,Bcous垃圾收集器处理它并且它将不再可用。
答案 3 :(得分:3)
问题,至少可能是其中的一部分,看起来像是阶级相互依赖。
初始化ApplicationProperties
实例时,您正在创建对MainBox
对象的引用,但在MainBox
类的定义中,您正在创建新的ApplicationsProperties
类。 1}}对象,它引用了MainBox
....我甚至让自己感到困惑。 MainBox
是您的父表单,即启动应用程序时加载的表单吗?
如果MainBox
中的某些内容在ApplicationProperites
类中设置了对它的引用,那么ApplicationProperties
中的某些内容会被摧毁...当你单击“X”时会被处置掉,我不会感到惊讶。再次,这是一个有根据的猜测;我不确定是不是这个原因,但即使代码不是错误本身,它对我来说也很古怪。
如果您希望ApplicationProperties
窗口永远持续并简化操作,只需在应用程序持续时间的任何形式的开头初始化它的静态实例,并显示/隐藏它类似你最初的尝试。如果你想要高效和基础,只要你需要让用户修改它,就构造和处理{{1}},但是杀死循环依赖。