我想实现一个“Popup”信息表单,该表单应该在各种场合显示(如鼠标悬停,上下文菜单等),并且应该在用户更改焦点时自动隐藏。
我决定使用SINGLETON模式,如下所示:
public class frmCellInfo : Form
{
public static frmCellInfo instance;
public static frmCellInfo GetInstance()
{
if (instance == null)
instance = new frmCellInfo();
return instance;
}
private frmCellInfo() // PRIVATE, because of Singleton
{
InitializeComponent();
}
private void frmCellInfo_Deactivate(object sender, EventArgs e)
{
this.Hide();
}
// ......
表单的调用如下:
frmCellInfo frm = frmCellInfo.GetInstance();
frm.Show();
基本上,自动显示/隐藏的工作方式与预期相同;但是,当用户通过单击“X”图标来关闭表单时,然后表单进入,下次,当我尝试访问表单时,我得到异常“无法访问已处置的对象”
所以当然,实例仍然是“那里”,但“处置”(?)
问题:我应该如何重写表单或单例模式的调用,以便在表单被“处理”时,我可以再次创建它?
答案 0 :(得分:4)
简单的答案是:你不应该。 Jon Skeet's description of the Singleton pattern非常贴切:
基本上,单例是一个只允许创建自己的单个实例的类,并且通常可以简单地访问该实例。
表单可能是单例实例的不良候选者 - 其状态可能会发生变化,您可能需要多次显示该表单。根据我的个人经验,单例实例的最佳候选者是可能是静态的类,但要么继承另一个类,要么必须实现一个或多个接口。 Form
不能很好地符合这些标准。
所以在实际情况下,实例仍然是"那里",但是"处理" (?)
是的,如果您真的想要,可以在catch
方法中ObjectDisposedException
GetInstance
并重新创建表单实例。这不是做到这一点的方式,实际上违背了单身人士的整个想法。在实施这样的黑客攻击之前,请三思而后行。
答案 1 :(得分:4)
您可以通过取消FormClosing
事件并隐藏表单来实现它。
CancelEventArgs.Cancel Property
private void frmCellInfo_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
this.Hide();
}
答案 2 :(得分:2)
您的参考frmCellInfo.instance
不为空,
当您通过X
按钮(已处理)
然后方法frmCellInfo.GetInstance()
返回对已处理实例的引用。
在FormClosed
eventhandler
private void frmCellInfo_FormClosed(object sender, FormClosedEventArgs e)
{
frmCellInfo.instance = null;
}
然后在方法frmCellInfo.GetInstance()
中,将根据需要创建新实例