2014-09-12 116 views
1

我想一次只保留一個活動子窗體。我想在以MDI形式開放任何孩子時處置其他孩子。 我已經嘗試了很多可能的方式沒有運氣。有一個單獨的類功能來完成骯髒的工作將是很好的。任何幫助將不勝感激。 下面是示例代碼窗體類:在VB.NET MDI表單中一次打開單個子窗體

進口的System.Reflection

Class closeHelper 

    Public Shared Sub HideAllForms() 
     Dim currentAssembly As Assembly = Assembly.GetExecutingAssembly() 
     Dim count As Integer = Application.OpenForms.Count 
     For i As Integer = 0 To count - 1 Step +1 
      Dim f As Form = Application.OpenForms(i) 
      If f.[GetType]().Assembly Is currentAssembly AndAlso f.Name <> "frmMDI" Then 'Here 'frmMDI' is the name of mdiform. 
       f.Close() 
      End If 
     Next 
    End Sub 

End Class 
+0

我收到以下錯誤把它稱爲:索引超出範圍。必須是非負數且小於集合的大小。 參數名稱:索引 – SOAMad 2014-09-12 19:33:41

+1

刪除時務必執行**反向**循環。 '對於我作爲整數=(count - 1)到0步-1'的基本知識。 – 2014-09-12 19:36:01

+0

是的,我知道,但是我認爲這可能有助於達到計數。我再次嘗試,結果是一樣的。出現錯誤「索引超出範圍,必須是非負數,並且小於集合的大小。 參數名稱:index」在Application.OpenForms(i)處,並且下劃線。 ({「索引超出範圍,必須是非負值,小於集合的大小 參數名稱:索引」}) – SOAMad 2014-09-12 19:39:57

回答

2

在刪除或執行修改集合的操作時,應始終使用反向循環。使用正向循環

For i As Integer = (count - 1) To 0 Step -1 

圖片此(的3項目的集合):

  1. 迭代:刪除/閉指標0,指數可供選擇:0,1,2,結果:OK。
  2. 迭代:刪除/關閉索引1,索引可用:0,1,結果:OK。
  3. 迭代:刪除/關閉索引2,索引可用:0,結果:錯誤。

正如你所看到的,最後會拋出一個IndexOutOfRangeException

0

好了,下面的代碼爲我工作。唯一的問題是,如果我點擊按鈕再次打開當前窗體,它似乎重新打開窗體。我再次測試它幾次。

Public Shared Sub HideAllForms() 
     Dim currentAssembly As Assembly = Assembly.GetExecutingAssembly() 
     Dim count As Integer = Application.OpenForms.Count 
     For i As Integer = (count - 1) To 0 Step -1 
      Dim f As Form = Application.OpenForms(i) 
      If f.[GetType]().Assembly Is currentAssembly AndAlso f.Name <> "HOME" Then 'Here 'HOME' is the name of mdiform. 
       f.Close() 
      End If 
     Next 
    End Sub 
+0

所以它確實工作?(指您的評論)也許我應該發表我寫的答案? (但沒有發佈,因爲你說它沒有工作) – 2014-09-12 20:01:08

1

您通常不應該在迭代它的同一個循環中修改集合。

發生什麼事情是,關閉表單後,它不再是OpenForms集合的一部分,因此您可以跳過其他表單。然後中途失敗,因爲索引已關閉。例如,假設你有3種形式。在索引0處,您將關閉表格#1,將所有打開的表格移動1.在索引1處,您具有表格#3(因爲#2現在在0以下)並關閉它。然後嘗試關閉索引#3的表單,但它不在那裏,現在只有一個項目在您的集合中(所以一個表單保持打開狀態並且您也會得到一個異常)。

而是將OpenForms複製到Form數組中,並執行相同的過程。

Public Shared Sub HideAllForms() 
    Dim currentAssembly As Assembly = Assembly.GetExecutingAssembly() 

    'remember which forms were open, we don't want to mess our indexes 
    Dim forms As New List(Of Form) 
    For Each frm in Application.OpenForms 
    forms.Add(frm) 
    Next 

    'iterate over all forms which were open at the start of this method 
    For Each f As Form in forms 
    If f.[GetType]().Assembly Is currentAssembly AndAlso f.Name <> "HOME" Then 'Here 'HOME' is the name of mdiform. 
     f.Close() 
    End If 
    Next 
End Sub 
+0

我想除了這個答案,但答案已經在我的代碼。你和我的代碼唯一的問題是,它會關閉並重新打開相同的表單,如果我按下按鈕兩次,這裏是調用代碼:closeHelper.HideAllForms() form2.Show() – SOAMad 2014-09-12 20:26:14

+0

@SOAMad:您已經接受回答。 SO上不能有超過一個被接受的答案。 – Neolisk 2014-09-12 20:32:03

1
Private Sub ToolStrip1_ItemClicked(sender As System.Object, e As System.Windows.Forms.ToolStripItemClickedEventArgs) Handles ToolStrip.ItemClicked 

Dim ToolStripClickedItem As String = e.ClickedItem.Name 
    Select Case ToolStripClickedItem 
     Case "ToolStripButtonEmployee" 
      For Each f As Form In Application.OpenForms 
       If TypeOf f Is frmEmployee Then 
        f.Activate() 
        Return 
       End If 
      Next 

      Dim childEmployee As New frmEmployee 
      childEmployee.MdiParent = Me 
      childEmployee.StartPosition = FormStartPosition.CenterScreen 
      childEmployee.Show() 
End sub 

我從ToolStripButtonEmployee.ToolStrip1_ItemClicked事件

+0

Kumari謝謝你讓我知道你是否可以做soem自由職業者 – SOAMad 2016-08-24 05:50:52

相關問題