10

我收到错误消息无法访问已处置的对象。对象名称:“应用程序属性”。当我在关闭表单后尝试重新打开表单时。我注意到这是来自退出表单,退出是它们的“处理”,因此我将以下代码放入所有接受按钮和取消按钮(关闭表单的任何按钮)中。

 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”按钮关闭程序后,我无法再次访问 form2,因为在ApplicationPropertiesWindow.Show();

在 form2 我有以下代码:

public partial class ApplicationProperties : Form
{
    //Creates and sets the instance MainBoxWindow.
    public MainBox MainBoxWindow { get; set; }
4

4 回答 4

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
   }

因为现在它仍在关闭表单,因此仍然导致错误。

于 2013-08-02T16:39:19.040 回答
5

在我使用第二个表单上的“x”按钮关闭程序后,我无法再次访问 form2,因为在 ApplicationPropertiesWindow.Show();

当表单关闭时(Form.Close),表单本身及其所有相关资源都将被释放。如文档中所述,此自动处置只有两个例外:

  1. 表单是 MDI 应用程序的一部分,可见。
  2. 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方法时是否将所有者窗口作为参数传递。

于 2013-08-03T05:28:04.853 回答
3

首先删除 this.Parent=null bcose 隐藏表单时不需要

现在,当您隐藏表单时,如果您仍想在静态 var 中访问此表单存储表单。Bcous 当对象不再使用时,垃圾收集器将其丢弃,它将不再可用。

于 2013-08-02T16:43:02.477 回答
3

这个问题,至少可能是其中的一部分,看起来有点像阶级相互依赖。

当你初始化一个ApplicationProperties实例时,你正在创建一个MainBox对象的引用,但是在MainBox类的定义中,你正在创建一个新的ApplicationsProperties对象,它引用了一个MainBox......我什至让自己感到困惑。您的父表单是MainBox您启动应用程序时加载的表单吗?

MainBox如果您在类中设置对它的引用,如果其中的某些内容被无意中破坏,我不会感到惊讶ApplicationProperites......当您单击“X”时,它正在处理。同样,这是有根据的猜测;我不确定这是否是原因,但即使代码本身没有,对我来说它看起来也很古怪。

如果您希望您的ApplicationProperties窗口永远存在并简化事情,只需在任何形式的开头初始化它的静态实例,以保持您的应用程序的持续时间,并显示/隐藏它类似于您最初尝试的内容。如果您想高效且基本,ApplicationProperties请在需要让用户修改它时构造和处置,但要杀死循环依赖。

于 2013-08-02T20:21:08.630 回答