单身形式:当表格被“处置”时如何处理案件

时间:2015-05-11 08:26:47

标签: c# winforms

我想实现一个“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”图标来关闭表单时,然后表单进入,下次,当我尝试访问表单时,我得到异常“无法访问已处置的对象”

所以当然,实例仍然是“那里”,但“处置”(?)

问题:我应该如何重写表单或单例模式的调用,以便在表单被“处理”时,我可以再次创建它?

3 个答案:

答案 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

中将其设置为null
private void frmCellInfo_FormClosed(object sender, FormClosedEventArgs e)
{
    frmCellInfo.instance = null;
}

然后在方法frmCellInfo.GetInstance()中,将根据需要创建新实例