События загрузки формы не обрабатываются при вызове формы во второй раз

#.net #vb.net #winforms #datagridview

#.net #vb.net #winforms #datagridview

Вопрос:

Почему не работает следующее?

Две формы; первая вызывает вторую. Во второй форме есть DataGridView — в ней нет столбцов, они добавляются программой вместе с DataGridViewButtonColumn .

Вызов Form2 в первый раз работает нормально. Но при повторном вызове кнопки не содержат текста.

 ' The first form - has one button, which calls Form2
Public Class Form1
    Friend fruit As New List(Of Fruit)

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        fruit.Add(New Fruit("Apple", "Red"))
        fruit.Add(New Fruit("Orange", "Orange"))
        fruit.Add(New Fruit("Banana", "Yellow"))
        fruit.Add(New Fruit("Melon", "Red"))
        fruit.Add(New Fruit("Pear", "Green"))
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Form2.ShowDialog()
    End Sub
End Class


Public Class Fruit
    Public Property name As String
    Public Property colour As String
    Public Sub New(newName As String, newColour As String)
        name = newName
        colour = newColour
    End Sub
End Class
  

Код для второй формы:

 ' Form2 has a button which closes the form, and a DataGridView
Public Class Form2
    Dim dataGridViewButtonColumn1 As DataGridViewButtonColumn
    Dim setupAlready As Boolean = False

    Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        dataGridViewButtonColumn1 = New DataGridViewButtonColumn
        DataGridView1.DataSource = Form1.fruit
        With dataGridViewButtonColumn1
            .Name = "ButtonCol"
            .UseColumnTextForButtonValue = False
        End With
        If Not setupAlready Then
            DataGridView1.Columns.Add(dataGridViewButtonColumn1)
        End If
        For i As Integer = 0 To 4
            DataGridView1.Rows(i).Cells("ButtonCol").Value = "Hello"
        Next
        setupAlready = True
    End Sub

    Private Sub DataGridView1_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) _
                Handles DataGridView1.CellContentClick
        Debug.Print(String.Format("Col={0}, Row={1}, ColName={2}", e.ColumnIndex, e.RowIndex, DataGridView1.Columns(e.ColumnIndex).Name))
        If (DataGridView1.Rows.Item(e.RowIndex).Cells("ButtonCol").Value Is "Hello") Then
            DataGridView1.Rows.Item(e.RowIndex).Cells("ButtonCol").Value = "GoodBye"
            DataGridView1.Rows(e.RowIndex).DefaultCellStyle.BackColor = Color.LightGreen
        End If
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Me.Close()
    End Sub
End Class
  

Ответ №1:

Я думаю, что у вас есть сходимость нескольких причин, вызывающих это. Во-первых, формы являются классами и должны создаваться явно. Вместо Form2.ShowDialog() этого сделайте это:

 Using frm As New Form2        ' create instance
   frm.ShowDialog
   ' do something
End Using                     ' dialogs are also a resource
  

Using / .Dispose не требуется для обычных форм, потому что при их закрытии они удаляются. Не так с диалогами, поскольку мы обычно просто скрываем их, чтобы мы могли получать из них информацию.

Далее, событие Form_Load вызывается только при ПЕРВОМ отображении формы. См. MSDN: Occurs before a form is displayed for the first time.

Таким образом, при повторном использовании не удаляемого Form2 события событие загрузки не вызывается, и код в событии загрузки не выполняется. Все должно работать нормально, если вы удаляете и создаете новые экземпляры формы. Кстати, это относится ко всем формам, а не только к диалоговым окнам.

Комментарии:

1. Спасибо, очень полезно, хорошо решает проблему! (Извините за медленный ответ, отсутствовал неделю).