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