2

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

我从实现一个单例模式开始,它在半途而废。如果 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
        }
    }

谢谢 :)

4

2 回答 2

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
        }
于 2013-01-19T20:15:18.270 回答
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();

它未经测试,但它应该遍历所有打开的表格并寻找任何有Tag说法的东西opened。如果遇到一个,那么它将shouldOpenNewDialog标志设置为 false 并且NewProfile不会被调用。

于 2013-01-19T19:34:01.947 回答