我正在使用.NET Windows Forms。我的MDI父表单包含菜单。如果单击菜单,将显示表单。到目前为止没有问题。
UserForm uf = new UserForm();
uf.Show();
uf.MdiParent = this;
如果再次单击该菜单,则会创建另一个表单副本。如何解决这个问题?
答案 0 :(得分:5)
最简洁的方法是简单地跟踪表单实例的生命周期。通过订阅FormClosed事件来这样做。例如:
private UserForm userFormInstance;
private void showUserForm_Click(object sender, EventArgs e) {
if (userFormInstance != null) {
userFormInstance.WindowState = FormWindowState.Normal;
userFormInstance.Focus();
}
else {
userFormInstance = new UserForm();
userFormInstance.MdiParent = this;
userFormInstance.FormClosed += (o, ea) => userFormInstance = null;
userFormInstance.Show();
}
}
答案 1 :(得分:4)
您应该创建一个 singleton 类来管理表单实例:
public class FormProvider
{
public static UserForm UserForm
{
get
{
if (_userForm== null || _userForm.IsDisposed)
{
_userForm= new UserForm ();
}
return _userForm;
}
}
private static UserForm _userForm;
}
注意,这是一个非常简单的Singleton模式。要使用该模式的正确方法,请使用此link。
然后您可以按如下方式访问表单:
FormProvider.UserForm.Show();
FormProvider.UserForm.MdiParent = this;
首次访问FormProvider.UserForm
时,将创建它。 FormProvider.UserForm
属性上的任何后续get都将返回在首次访问时创建的表单。这意味着表单只会被创建一次。
答案 2 :(得分:4)
与此处的现有答案相反,我不建议使用Singleton。 Singleton模式过度使用,通常是一种“代码味”,表明整体设计出了问题。单身人士通常与全局变量放在同一个“桶”中:你最好有一个非常强大的使用它的案例。
最简单的解决方案是在主窗体上创建一个表示相关窗体的实例变量,然后用它来显示它。
public class MainMdiForm : Form
{
...
UserForm userForm;
...
private void ShowUserForm()
{
if(userForm == null || userForm.IsDisposed)
{
userForm = new UserForm();
userForm.MdiParent = this;
}
userForm.Show();
userForm.BringToFront();
}
}
答案 3 :(得分:3)
如果您知道表单的名称:
if (Application.OpenForms["FormName"] == null)
{
Form form = new Form();
form.MdiParent = this;
form.Show();
}
else
Application.OpenForms["FormName"].Focus();
答案 4 :(得分:0)
您可以随时将表单设为单身人士:
public class MyForm : Form
{
private MyForm _instance = null;
private object _lock = new object();
private MyForm() { }
public static MyForm Instance
{
get
{
if (_instance == null)
{
lock (_lock)
{
if (_instance == null)
_instance = new MyForm();
}
}
return _instance;
}
}
}
然后你的电话会是这样的:
MyForm.Instance.Show();
MyForm.Instance.MdiParent = this;
答案 5 :(得分:0)
选项:
UserForm
成为单身人士:http://msdn.microsoft.com/en-us/library/ff650316.aspx menuItem.Enabled = false;
通常,禁用按钮工作正常,从用户的角度来看更有意义。如果你需要为其他东西启用按钮,Singleton可以工作。
如果可以关闭表单并且以后需要新的实例,那么Singleton可能不是是一个很好的解决方案。答案 6 :(得分:0)
您可以检查主机表单的MdiChildren属性,以确定其中是否存在UserForm的实例。
UserForm myForm = null;
foreach (Form existingForm in this.MdiChildren)
{
myForm = existingForm as UserForm;
if (myForm != null)
break;
}
if (myForm == null)
{
myForm = new UserForm();
myForm.MdiParent = this;
myForm.Show();
}
else
myForm.Activate();
这将创建一个新的UserForm实例,它尚不存在,如果它存在,它将切换到创建的实例。
答案 7 :(得分:0)
这是我在ShowForm()中的解决方案,并在aboutToolStripMenuItem_Click()中调用示例:
private void ShowForm(Type typeofForm, string sCaption)
{
Form fOpen = GetOpenForm(typeofForm);
Form fNew = fOpen;
if (fNew == null)
fNew = (Form)CreateNewInstanceOfType(typeofForm);
else
if (fNew.IsDisposed)
fNew = (Form)CreateNewInstanceOfType(typeofForm);
if (fOpen == null)
{
fNew.Text = sCaption;
fNew.ControlBox = true;
fNew.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
fNew.MaximizeBox = false;
fNew.MinimizeBox = false;
// for MdiParent
//if (f1.MdiParent == null)
// f1.MdiParent = CProject.mFMain;
fNew.StartPosition = FormStartPosition.Manual;
fNew.Left = 0;
fNew.Top = 0;
ShowMsg("Ready");
}
fNew.Show();
fNew.Focus();
}
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
ShowForm(typeof(FAboutBox), "About");
}
private Form GetOpenForm(Type typeofForm)
{
FormCollection fc = Application.OpenForms;
foreach (Form f1 in fc)
if (f1.GetType() == typeofForm)
return f1;
return null;
}
private object CreateNewInstanceOfType(Type typeofAny)
{
return Activator.CreateInstance(typeofAny);
}
public void ShowMsg(string sMsg)
{
lblStatus.Text = sMsg;
if (lblStatus.ForeColor != SystemColors.ControlText)
lblStatus.ForeColor = SystemColors.ControlText;
}
public void ShowError(string sMsg)
{
lblStatus.Text = sMsg;
if (lblStatus.ForeColor != Color.Red)
lblStatus.ForeColor = Color.Red;
}