我正在编写一个应用程序,它使用一系列类似向导的5个简单表单。第一个表单NewProfile是从主应用程序MainForm上的菜单项打开的,它是MainForm的子表单。第二个表单TwoProfile是通过NewProfile上的按钮打开的。第三个表单是通过TwoProfile上的按钮打开的,依此类推,所有5个表单都是如此。下面是顺序:MainForm -> NewProfile <-> TwoProfile <-> ThreeProfile <-> FourProfile <-> FiveProfile。我的问题是,当任何形式(NewProfile, TwoProfile, ThreeProfile, FourProfile或FiveProfile)打开时,我不希望用户能够创建NewProfile的实例。
我开始时实现了一个Singleton模式,它可以工作一半。它的工作原理,如果NewProfile是打开的,我去MainForm,并尝试创建NewProfile的另一个实例。它不工作,如果NewProfile已被销毁,通过推进到下一个形式和一个TwoProfile, ThreeProfile, FourProfile或FiveProfile是打开的。它告诉我NewProfile。isdispose为true,这给了我一个糟糕的Singleton实例引用。
我无法弄清楚的是如何做我的逻辑,使NewProfile不会被创建,如果一个TwoProfile, ThreeProfile, FourProfile或FiveProfile是打开的,或者如果NewProfile本身是打开的。
我希望这是有意义的。我真的没有太多的代码要发布,除了我为我的Singleton所做的。 private static NewProfile _instance = null;
public static NewProfile Instance
{
get
{
if (_instance == null)
{
_instance = new NewProfile();
}
return _instance
}
}
谢谢你
正如评论中建议的那样,每个"表单"实际上可以是您交换的用户控件。这样,您就只有一个表单和多个页面。或者,您可以隐藏表单。
如果您想要多个表单,那么您可以遍历所有打开的表单,看看您想要检查的表单是否打开。如果没有,可以打开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
。
我们处理这个问题的方法是使用一个静态窗口管理器类来跟踪打开的表单实例。当用户执行将导致打开新窗口的操作时,我们首先检查窗口管理器,看看表单是否已经打开。如果是,我们将焦点放在它上面,而不是创建一个新的实例。
每个打开的窗体都继承自一个基本窗体实现,该窗体在打开时自动向窗口管理器注册自己,并在关闭时删除其注册。
下面是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
}