一次只打开一个子表单实例c#

时间:2013-01-19 19:23:18

标签: c# subforms

我正在编写一个使用类似向导的5个简单表单系列的应用程序。第一个表单NewProfile是从主应用程序MainForm上的菜单项打开的,因此是MainForm的子表单。第二种形式TwoProfile是从NewProfile上的按钮打开的。第三种形式,ThreeProfile是从TwoProfile上的按钮打开的,依此类推所有5种形式。这是序列: MainForm - > NewProfile< - > TwoProfile< - > ThreeProfile< - > FourProfile< - > FiveProfile。我的问题是,当打开任何表单(NewProfile,TwoProfile,ThreeProfile,FourProfile或FiveProfile)时,我不希望用户能够创建NewProfile的实例。

我开始实现一个Singleton模式,它中途工作。如果NewProfile处于打开状态并且我转到MainForm并尝试创建另一个NewProfile实例,它就可以工作。如果NewProfile已被销毁,则无法工作,方法是前进到下一个表单,并打开TwoProfile,ThreeProfile,FourProfile或FiveProfile之一。它告诉我NewProfile.IsDisposed是真的,给我一个对Singleton实例的错误引用。

我无法弄清楚如何处理我的逻辑,以便在TwoProfile,ThreeProfile,FourProfile或FiveProfile中的一个打开或NewProfile本身打开时不会创建NewProfile。

我希望这是有道理的。除了我为Singleton做的事情之外,我真的没有太多的代码可以发布。

   private static NewProfile _instance = null;
   public static NewProfile Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = new NewProfile();
            }
            return _instance
        }
    }

谢谢:)

2 个答案:

答案 0 :(得分:1)

正如评论中所建议的,每个“表单”实际上可能是您交换的用户控件。这样,您只有一个表单和多个页面。或者,您可以隐藏表单。

如果您想要多个表单,那么您可以遍历所有打开的表单,并查看您要检查的表单是否已打开。如果没有,您可以打开NewProfile

bool shouldOpenNewDialog = true;

foreach (Form f in Application.OpenForms)
{       
    //give each dialog a Tag value of "opened" (or whatever name)
    if (f.Tag.ToString() == "opened")
        shouldOpenNewDialog = false;    
}


if(shouldOpenNewDialog)
    np = new NewProfile();

它未经测试,但它应遍历所有打开的表单,并查找Tagopened的任何内容。如果遇到一个,则会将shouldOpenNewDialog标记设置为false,并且不会调用NewProfile

答案 1 :(得分:1)

我们处理这个问题的方法是使用一个静态窗口管理器类来跟踪打开的表单实例。当用户执行会导致打开新窗口的操作时,我们首先检查窗口管理器以查看窗体是否已打开。如果是,我们将重点放在它上面而不是创建一个新实例。

每个打开的表单都继承自一个基本表单实现,它在打开时会自动向窗口管理器注册,并在关闭时删除它的注册。

以下是WindowManager类的大致轮廓:

public class WindowManager
{
    private static Dictionary<string, Form> m_cOpenForms = new Dictionary<string, Form>();

    public static Form GetOpenForm(string sKey)
    {
        if (m_cOpenForms.ContainsKey(sKey))
        {
            return m_cOpenForms[sKey];
        }
        else
        {
            return null;
        }
    }
    public static void RegisterForm(Form oForm)
    {
        m_cOpenForms.Add(GetFormKey(oForm), oForm);
        oForm.FormClosed += FormClosed;
    }

    private static void FormClosed(object sender, FormClosedEventArgs e)
    {
        Form oForm = (Form)sender;
        oForm.FormClosed -= FormClosed;
        m_cOpenForms.Remove(GetFormKey(oForm);
    }

    private static string GetFormKey(Form oForm)
    {
        return oForm.Name;
    }
}

你可以按如下方式使用它:

        Form oForm = WindowManager.GetOpenForm("Form1");
        if (oForm != null)
        {
            oForm.Focus();
            oForm.BringToFront();
        }
        else
        {
            oForm = new Form1();
            WindowManager.RegisterForm(oForm);
            // Open the form, etc
        }