2011-07-12 23 views
8

Tôi muốn tránh biểu mẫu của con tôi xuất hiện nhiều lần khi người dùng cố gắng mở biểu mẫu con đã được mở trong MDIParent. Một cách để tránh điều này là vô hiệu hóa Bộ điều khiển (trong trường hợp BUTTON) nhưng tôi đã đưa ra một phím tắt (Ctrl + L) cho chức năng này. Vì vậy, nếu người dùng nhập Ctrl + L, cùng một biểu mẫu con mở ra và tôi có thể thấy hai biểu mẫu con trong MDI.Cách tránh nhiều biểu mẫu Con được hiển thị trong MDIParent C# Win Forms

private void leadsToolStripMenuItem_Click(object sender, EventArgs e) 
    { 
     frmWebLeads formWeblead = new frmWebLeads(); 
     formWeblead.MdiParent = this; 
     formWeblead.WindowState = System.Windows.Forms.FormWindowState.Maximized; 
     formWeblead.Show(); 

    } 

Tôi muốn tránh điều này. Tôi có thể làm cái này như thế nào? enter image description here

Trong hình ảnh bạn có thể thấy rằng một đứa trẻ Tên hình thức online Dẫn được mở ra gấp đôi so với người dùng mở lần đầu tiên sử dụng Menu (tiềm năng) và lần thứ hai bằng phím tắt. Tôi không muốn điều này xảy ra. Nếu biểu mẫu đã được mở, bạn nên tránh mở một biểu mẫu khác ... Làm thế nào để thực hiện việc này?

Trả lời

4

cách tôi thường làm điều đó nếu tôi đang chỉ cho là có một mở là một cái gì đó như:

//class member for the only formWeblead 
frmWebLeads formWebLead = null; 

private void leadsToolStripMenuItem_Click(object sender, EventArgs e) 
{ 
    if (formWebLead == null) 
    { 
     formWeblead = new frmWebLeads(); 
     formWeblead.MdiParent = this; 
    } 

    formWeblead.WindowState = System.Windows.Forms.FormWindowState.Maximized; 
    formWeblead.Show(); 
} 
0

Cách đơn giản nhất là để giữ một tham chiếu đến các hình thức đứa trẻ, và chỉ đẻ trứng một cái mới nếu nó chưa tồn tại. Một cái gì đó như thế này:

class ParentForm : Form { 
    frmWebLeads formWeblead = null; 

    //... 

    private void leadsToolStripMenuItem_Click(object sender, EventArgs e) 
    { 
     if(formWeblead != null) return; 
     formWeblead = new frmWebLeads(); 
     formWeblead.MdiParent = this; 
     formWeblead.WindowState = System.Windows.Forms.FormWindowState.Maximized; 
     formWeblead.Show(); 

    } 

} 

Bạn cũng cần mã để thiết lập formWeblead null khi bạn đóng nó, nhưng tôi chắc chắn rằng bạn có thể tìm phần đó ra :)

+0

@ Mike Caron cảm ơn Mã của bạn. Phần cuối cùng bạn để lại cho tôi tạo ra một số nhầm lẫn, có nghi ngờ rằng formWeblead i n khai báo MDIParent và tôi nghĩ rằng để thiết lập formWeblead = null bằng cách sử dụng frmWebLoad để lại Event sử dụng Child để truy cập cha mẹ, nó có ổn không !! ??? hoặc là có bất kỳ phương pháp tốt nhất có sẵn – panindra

+1

Tôi không nghĩ rằng tôi sẽ sử dụng sự kiện Rời khỏi, vì đó là một điều tập trung. Thay vào đó, hãy sử dụng sự kiện Đóng của biểu mẫu con, điều này sẽ kích hoạt khi bạn đóng nó. –

+0

@Mike Điều này để lại một số TODO liên quan đến mục menu gọi sự kiện nhấp chuột; Tôi muốn vô hiệu hóa mục menu đã tạo biểu mẫu để tránh nhầm lẫn với người dùng, ví dụ: "Tôi đang nhấp vào 'mở' và không có gì xảy ra". – gangelo

3
private void leadsToolStripMenuItem_Click(object sender, EventArgs e) 
{ 
    formWeblead formWeblead = null; 
    if ((formWeblead = IsFormAlreadyOpen(typeof(frmWebLeads)) == null) 
    { 
     formWeblead = new frmWebLeads(); 
     formWeblead.MdiParent = this; 
     formWeblead.WindowState = System.Windows.Forms.FormWindowState.Maximized; 
     formWeblead.Show(); 
    } 
} 

public static Form IsFormAlreadyOpen(Type FormType) 
{ 
    foreach (Form OpenForm in Application.OpenForms) 
    { 
     if (OpenForm.GetType() == FormType) 
     return OpenForm; 
    } 

    return null; 
} 
+0

Tôi xin lỗi, nhưng tôi không có vấn đề tương tự. Tôi đang chạy .NET 3.5 trên VS 2008. Tôi có thể đóng và chỉ mở một biểu mẫu liên tục. – Joe

+0

tôi đang sử dụng .net 3.5 và VS 2010 Ultimate, Windows Xp ..là lỗi đánh dấu này – panindra

0
// Implementation of the below class in your MDI Parent 
private void openToolStripMenuItem_Click(object sender, EventArgs e) { 
      if (SingletonForm.Exists) { 
       return; 
      } else { 
       m_openToolStripMenuItem.Enabled = false; 

       SingletonForm form = new SingletonForm(); 
       form.FormClosed += new FormClosedEventHandler(
        delegate(object _sender, FormClosedEventArgs _e) { 
         m_openToolStripMenuItem.Enabled = true; 
        }); 
       form.MdiParent = this;    
       form.Show(); 
      } 
     } 


// SingletonForm Class 
    using ... 
    using System.Threading; 

    namespace SingletonForm { 

     public partial class SingletonForm : Form, IDisposable { 
      static private readonly string m_mutexName = "SingletonForm.SingletonForm"; 
      private Mutex m_mutex; 
      private bool m_disposed; 

      public SingletonForm() { 
       m_disposed = false; 

       // Check to see if there is already a running instance... 
       bool owned; 
       m_mutex = new Mutex(true, m_mutexName, out owned); 
       if (!owned) { 
        // Already running, get out... 
        Close(); 
        return; 
       } 

       InitializeComponent(); 
      } 

      ~SingletonForm() { 
       Dispose(false); 
      } 

      static public bool Exists { 
       get { 
        bool owned; 
        using (new Mutex(false, m_mutexName, out owned)) { 
         return !owned; 
        } 
       } 
      } 

      // IDisposable Members 
      // -------------------------------------------------------------------------- 
      #region IDisposable Members 
      new public void Dispose() { 
       Dispose(true); 

       // Use SupressFinalize in case a subclass of this type implements a finalizer. 
       GC.SuppressFinalize(this); 
      } 
      #endregion // IDisposable Members 

      /// <summary> 
      /// Note: Comment out the Dispose(bool disposing) implementation in your 
      /// SingletonForm.Designer.cs 
      /// </summary> 
      /// <param name="disposing">true if we are disposing.</param> 
      protected override void Dispose(bool disposing) { 
       if (disposing && (components != null)) { 
        components.Dispose(); 
       } 

       base.Dispose(disposing); 

       // If you need thread safety, use a lock around these 
       // operations, as well as in your methods that use the resource. 
       if (!m_disposed) { 
        if (disposing) { 
         // Code to dispose the managed resources held by the class here... 
         if (m_mutex != null) { 
          m_mutex.Dispose(); 
          m_mutex = null; 
         } 
        } 

        // Indicate that the instance has been disposed. 
        m_disposed = true; 
       } 
      } 
     }; 
    }; 

Sẽ có được tốt đẹp để sử dụng semaphores thay vì để cho phép 1-n trường tồn tại.

0

Đây là "Phương thức" mà tôi đã tạo để Gọi chỉ mở một biểu mẫu khi bạn nhấp vào Menu trong MDIParent. Hy vọng "Phương pháp" này có thể giúp bạn!

Cách sử dụng: On Even ToolStripMenuItems.

Form1 frm1 = new Form1(); 
CheckActiveChildForm(frm1,"myForm"); 

//myForm is the Text of Form1 
private void CheckActiveChildForm(Form FormControl, string FormExists) 
{ 
    int h = 0; 
    if (MdiChildren.Count() == 0) 
    { 
     //Form2 childF = new Form2(); 
     FormControl.MdiParent = this; 
     FormControl.Show(); 
    } 

    if (MdiChildren.Count() > 0) 
    { 
     for (int i = 0; i < MdiChildren.Count(); i++) 
     { 
      if (MdiChildren.ElementAt(i).Text == FormExists) 
      { 
       h = 1; 
      } 
     } 
    } 

    if (h == 0) 
    { 
     FormControl.MdiParent = this; 
     FormControl.Show(); 
    } 
} 
+0

Tại sao lưu ý? –

4

Set này ở dạng chính của bạn) chức năng (

InitializeComponent(); 
    this.WindowState = FormWindowState.Maximized; 
    this.ShowInTaskbar = true; 

from_login login = new from_login(); 
       login.MdiParent=this; 
       login.Show(); 
       pmsnrr.pmsmain = this; 

và đây là mã đi bên trong dải menu sự kiện trơn

if (this.ActiveMdiChild != null) 
      this.ActiveMdiChild.Close(); 
      frm_companymaster company = new frm_companymaster(); 
      company.MdiParent = this; 
      company.WindowState = FormWindowState.Normal; 
      company.Show(); 
0

Bạn có thể kiểm tra các hình thức mở hiện tại để đạt được điều đó:

if (Application.OpenForms.Count == 1) { 
    ReportProductDetails Report9 = new ReportProductDetails(); 
    Report9.MdiParent = this; 
    Report9.Show(); 
    Report9.Activate(); 
} 
else { 
    MessageBox.Show("Sorry!Close the All the Exist Form,Before open this Form", "Information", MessageBoxButtons.OK, MessageBoxIcon.Error); 
} 
0

Tôi sử dụng giải pháp này, với một mẹo nhỏ

frmWebLeads formWebLead = null; 

private void leadsToolStripMenuItem_Click(object sender, EventArgs e) 
    { 
     if (formWebLead == null || formWebLead.isAccessible == false) 
     { 
      formWeblead = new frmWebLeads(); 
      formWeblead.MdiParent = this; 
     } 

     formWeblead.WindowState = System.Windows.Forms.FormWindowState.Maximized; 
     formWeblead.Show(); 
    } 
1
frmWebLeads formWeblead; 

    bool isformWebleadOpen =false; 

    private void leadsToolStripMenuItem_Click(object sender, EventArgs e) 
    { 
     if(isformWebleadOpen == false) 
     { 
     formWeblead = new frmWebLeads(); 
     isformWebleadOpen =true; 
     formWeblead.Closed += formWeblead_Closed; 
     formWeblead.Show(); 
     } 
    } 

    void formWeblead_Closed(object sender, EventArgs e) 
    { 
    isformWebleadOpen = false; 
    } 
2

Cá nhân tôi thích một việc thực hiện chung:

private void ShowOrActivateForm<T>() where T : Form 
     { 
      var k = MdiChildren.Where(c => c.GetType() == typeof(T)).FirstOrDefault(); 
      if (k == null) 
      {      

       k = (Form)Activator.CreateInstance(typeof(T)); 
       k.MdiParent = this; 
       k.Show(); 
      } 
      else 
      { 
       k.Activate();     
      }    
     } 

Sau đó, bạn chỉ có thể sử dụng nó như thế này:

ShowOrActivateForm<myForm>(); 

đâu myForm là TYPE của biểu mẫu bạn muốn tạo

+0

Tôi thích cách tiếp cận này. Nó có khả năng mở rộng hơn nhiều so với việc tạo các trường trống cho mỗi đứa trẻ. 1 cho generics. Tôi muốn được quan tâm để biết nếu có bất kỳ chi phí bổ sung đáng chú ý cho việc sử dụng sự phản ánh; mặc dù ở mức rất cao. – Apache

+1

Tôi muốn tưởng tượng bất kỳ chi phí bổ sung nào sẽ không đáng kể. Nó chỉ chạy khi bạn thử và mở một biểu mẫu, do đó, trừ khi bạn đang mở hàng tấn biểu mẫu cùng một lúc, tôi không thể tưởng tượng nó sẽ có tác động đến hiệu suất ứng dụng hoặc trải nghiệm người dùng của bạn. –

+0

Tốt. Tôi cho rằng trong một ứng dụng có thể mở rộng, bạn sẽ sử dụng IoC Container của bạn, thay vì dựa vào 'Activator'. Tôi đã sử dụng phương pháp này với RadDock ngay bây giờ, để theo dõi MDI Children và Tool Windows. Tôi đã lấy 'Show()' và 'Activate()' ra, và trả về dạng thô dưới dạng 'T', để nó có thể được neo khi cần. – Apache

0

Mã, giúp ngăn chặn các hình thức con cùng ở dạng MDI

private void materialToolStripMenuItem_Click(object sender, EventArgs e) 
{ 
    frmMaterial newMDIChild = new frmMaterial(); 
    bool opened = false; 
    foreach (Form OpenForm in Application.OpenForms) 
    { 
    if (OpenForm.GetType() == typeof(frmMaterial)) 
    { 
     OpenForm.Activate();//to bring the activated form to the front 
     opened = true; 
    } 
    } 
    if (opened==false) 
    { 
    // Set the Parent Form of the Child window. 
    newMDIChild.MdiParent = this; 
    //newMDIChild.WindowState = System.Windows.Forms.FormWindowState.Maximized; 
    // Display the new form. 
    newMDIChild.Show(); 
    } 
} 
0
private void mnuMyForm_Click(object sender, EventArgs e) // click to open MyForm 
    { 
     foreach (Form item in this.MdiChildren) // check all opened forms 
     { 
      if (item.Name == "MyFormName") // check by form name if it's opened 
      { 
       item.BringToFront(); // bring it front 
       return; //exit 
      } 
     } 

     // if MyForm is not opened 
     // you know what it is 
     MyForm frm = new MyForm(); 
     frm.MdiParent = this; 
     frm.Show(); 
    } 
1

Fists thời gian khi bạn mở biểu mẫu từ menu, biến frmRep là null

frmReportes frmRep = null 

... do đó, Tôi thêm một "if" khác vào "if" để xác nhận form của tôi, bởi vì tôi có một form khác, sau đó nếu nó không nhìn thấy, tôi tạo một instance và hiển thị form, nhưng nếu hiển thị, tôi chỉ sử dụng Activate()

private void rToolStripMenuItem_Click(object sender, EventArgs e) 
    { 
     if (frmRep != null) 
     { 
      if (frmRep.Visible == false) 
      { 
       frmRep = new frmReportes(); 
       frmRep.MdiParent = this; frmRep.Show(); 
      } 
      else 
      {      
       frmRep.Activate(); 
       return; 
      } 
     } 
     else 
     { 
      frmRep = new frmReportes(); 
      frmRep.MdiParent = this; 
      frmRep.Show(); 
     }    
    } 
0

cách simpleist ngăn chặn nhiều thể hiện của con

private void Showforms(Form frm) 
{ 
    if (this.ActiveMdiChild==null) 
    { 
     frm.MdiParent = this; 
     frm.Show(); 
    } 
} 
0

Những cách đơn giản nhất của việc ngăn ngừa nhiều thể hiện của trẻ:

private void Showforms(Form frm) 
{ 
    if (this.ActiveMdiChild==null) 
    { 
     frm.MdiParent = this;    
     frm.Show(); 
    } 
} 

Sau đó gọi nó là như thế này:

Form1 frm = new Form1(); 
Showforms(frm); 
Các vấn đề liên quan