防止重复的MDI子表单

有没有办法阻止在MDI容器中打开某个表单,如果该表单已经打开?

您可以对OpenForms集合进行交互,以检查是否已存在给定类型的表单:

foreach (Form form in Application.OpenForms) { if (form.GetType() == typeof(MyFormType)) { form.Activate(); return; } } Form newForm = new MyFormType(); newForm.MdiParent = this; newForm.Show(); 

AFAIK没有标准的方法。 你必须自己实现它。 我这样做:

 class TheForm: Form { private static TheForm Instance; private TheForm() // Constructor is private { } public static Show(Form mdiParent) { if ( Instance == null ) { // Create new form, assign it to Instance } else Instance.Activate(); // Not sure about this line, find the appropriate equivalent yourself. } protected override OnFormClose(EventArgs e) { Instance = null; base.OnFormClose(e); } } 

如果需要考虑线程安全性,请添加适当的lock

请参阅http://gurucoders.blogspot.com/2009/08/avoid-duplicate-child-form-in-mdi.html

这段代码有效

  private void openToolStripMenuItem_Click(object sender, EventArgs e) { foreach (Form form in Application.OpenForms) { if (form.GetType() == typeof(Form2)) { form.Activate(); return; } } Form2 newForm = new Form2(); newForm.MdiParent = this; newForm.Show(); } 

虽然这篇文章很老,但我认为这会增加一些帮助。

如果表格最小化也需要处理。 这是完整的例子:

 foreach (Form form in this.MdiChildren) { if (form.GetType() == typeof(frmMain)) { if (form.WindowState == FormWindowState.Minimized) { form.WindowState = FormWindowState.Normal; } form.Activate(); return; } } Form frm = new frmMain(); frm.MdiParent = this; frm.Show(); 

这段代码在vb.net中适合我


对于每个f作为Application.OpenForms中的表单
如果TypeOf f是form_name那么
f.Activate()
f.WindowState = FormWindowState.Normal
f.StartPosition = FormStartPosition.WindowsDefaultLocation
f.WindowState = FormWindowState.Maximized

  Return End If Next form_name .MdiParent = Me form_name .Show() 

可以使用Generics(在C#和VB.net下面选项)实现一个方法,如果需要打开不同的MDI表单,这可能很有用。

C#

 private void OpenMDI(bool multipleInstances) where T : Form, new() { if (multipleInstances == false) { // Look if the form is open foreach (Form f in this.MdiChildren) { if (f.GetType() == typeof(T)) { // Found an open instance. If minimized, maximize and activate if (f.WindowState == FormWindowState.Minimized) { f.WindowState = FormWindowState.Maximized; } f.Activate(); return; } } } T newForm = new T(); newForm.MdiParent = this; newForm.Show(); } 

使用如下(在multipleInstances指示false以防止它们)

 OpenMDI(false); 

VB.NET

 Public Sub Open_MDI(Of T As {New, Form})(bMultipleInstances As Boolean) If bMultipleInstances = False Then For Each f As Form In Me.MdiChildren If TypeOf f Is T Then If (f.WindowState = FormWindowState.Minimized) Then f.WindowState = FormWindowState.Maximized; End If f.Activate() Exit Sub End If Next End If Dim myChild As New T() myChild.MdiParent = Me myChild.Show() End Sub 

使用如下(对于bMultipleInstances指示False以防止它们)

 Open_MDI(Of Form2)(False) 
  • ComboBox SelectionChanged事件触发较晚
  • .NET应用程序中的性能监控/指标
  • 如何将表名传递给SqlCommand?
  • 创建DirectoryEntry实例以用于测试
  • 如何在Microsoft Bot Framework中避免“抱歉,我的机器人代码有问题”
  • ThreadStateException:尝试加入线程时尚未启动Thread
  • 以编程方式设置要从序列化中排除的属性
  • 如何部署具有多个区域的asp.net mvc 4应用程序
  • 相同的变量名称 – 2个不同的类 – 如何将值从一个复制到另一个 – reflection – C#
  • C#中’is’reflection的性能特征是什么?
  • 显示行打破asp.net mvc razor