Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 表格不';当关闭并从另一个类引用时,t变为null_C#_Winforms - Fatal编程技术网

C# 表格不';当关闭并从另一个类引用时,t变为null

C# 表格不';当关闭并从另一个类引用时,t变为null,c#,winforms,C#,Winforms,我需要帮助解决下面的问题 我正在创建一个带有MDI接口的Windows窗体应用程序。在我的应用程序中,我创建了一个类,它基本上处理所有子窗体的所有打开/关闭,我们称之为fmanager。此外,它还检查表单实例是否打开。如果是这样,它不允许用户打开表单的另一个实例。这就是我的问题所在。 当用户要求打开窗口时,fmanager会显示以下代码: if (frm1 == null) { frmOne = new frm1(); frmOne.MdiParent = Main.Active

我需要帮助解决下面的问题

我正在创建一个带有MDI接口的Windows窗体应用程序。在我的应用程序中,我创建了一个类,它基本上处理所有子窗体的所有打开/关闭,我们称之为fmanager。此外,它还检查表单实例是否打开。如果是这样,它不允许用户打开表单的另一个实例。这就是我的问题所在。 当用户要求打开窗口时,fmanager会显示以下代码:

if (frm1 == null)
{
    frmOne = new frm1();
    frmOne.MdiParent = Main.ActiveForm; //Main is the parent form
}
frmOne.Show();
现在,当窗口第一次打开时,此代码可以正常工作。假设frm1已关闭并要求再次打开。再次执行上述代码,但是,frm1不等于NULL。我已经在FManage类的上面代码中设置了一个断点,它显示了frm1!=空,即使frm1已关闭。我认为问题在于,frm1,因为它作为引用存储在FManage中,并没有告诉FManage它是空的FManage只存储表单的初始状态,类似于静态变量。 我是OOP新手,正在寻找解决这个问题的最佳方法

我的第一个解决方案是,在frm1关闭之前,可能在FormClosing事件中,向FManager类发送一条消息,将frm1设置为null;然而,为了做到这一点,frm1类需要了解fmanager,而现在它还没有fmanager了解frm1,而不是相反。分享不是相互的。 仅供参考,frm1定义为我的类定义后的方法:

public class FManage
{
    frmOne frm1;
 ...
}

任何关于如何解决这个问题的建议都将不胜感激

A
Form
是一个与任何其他对象一样的对象。它的生命周期由它是否仍然可到达来控制。因此,隐藏(关闭)表单永远不会破坏对象或将任何内容设置为
null

您需要处理表单的事件才能知道它何时关闭。

:

关闭窗体时,对象中创建的所有资源都将被关闭 关闭并释放窗体。您可以阻止关闭表单 在运行时处理关闭事件并设置取消 作为参数传递给事件的CancelEventArgs的属性 处理程序。如果您要关闭的表单是您的 应用程序,应用程序结束

关闭时未处理窗体的两个条件是(1)它 是多文档接口(MDI)应用程序的一部分 形式是看不见的;以及(2)您已使用 显示对话框。在这些情况下,您需要手动调用Dispose以 将窗体的所有控件标记为垃圾回收


如果frmOne没有超出范围,它就不会被处置。它将保留您给它的任何值(在本例中是frm1的一个实例)。您可以在每次需要显示frm1对象时创建一个新的frm1对象(如果需要)。

一个选项是如您所述处理FormClosing事件。您不需要表单来“了解”FManage。您可以让FManager按如下方式订阅事件:

frm1.FormClosing += this.FormClosing; // this is FManage
另一个选项是在创建子窗体时检查窗体的Visible属性是否为true

if (frmOne == null || !frmOne.Visible)
{
    frmOne = new frm1();
    frmOne.MdiParent = Main.ActiveForm; //Main is the parent form
}
else
{
    // form is already created.  maybe bring to front?
    frmOne.BringToFront();
}

解决问题的关键是FormClosing事件的子类化。
在打开表单时设置该事件的处理程序。
然后在这种情况下(如果您同意关闭),将您的全局var设置为null。
这将正确重置您的逻辑,以打开frmOne的新实例。
不要混淆frmOne(类)和frm1(frmOne的实例)


另一种解决方案是迭代My.Application.OpenForms集合,检查哪些表单处于打开状态。
当调用它们的onFormClosed内部方法/事件时,它们将从此集合中删除。

您可以使用lambda:

public class FManage 
{ 
    frmOne frm1; 
    ... 

    // Here test on frm1 and create a new instance of frm1
    if (frm1 == null) 
    { 
        frm1 = new frmOne(); 
        frm1.FormClosing += (sndr, evnt) => { frm1 = null; };
        frm1.MdiParent = this; 
    } 
    frm1.Show(); 

    ...

} 

非常感谢。我应该先看一下文件。由于表单是MDI接口的一部分,因此在关闭表单时不会对其进行处理。这很有帮助,谢谢。是的,我通过订阅frm1的FormClose事件来接近答案。这非常有效。这正是我需要的。我第一次真正主持一个活动。我希望我能像你一样接受多个答案,Steve Wong的“黑暗猎鹰”建议正是我所需要的。
public class FManage 
{ 
    frmOne frm1; 
    ... 

    // Here test on frm1 and create a new instance of frm1
    if (frm1 == null) 
    { 
        frm1 = new frmOne(); 
        frm1.FormClosing += (sndr, evnt) => { frm1 = null; };
        frm1.MdiParent = this; 
    } 
    frm1.Show(); 

    ...

}