Не удается получить доступ к удаленному объекту в VB.NET

#vb.net #visual-studio

#vb.net #visual-studio

Вопрос:

Возникла небольшая проблема.

Я получаю Cannot access a disposed object сообщение об ошибке для Form1

При нажатии на пункт меню в главной форме — Sub вызывается ниже, который открывает другую форму Form1

 Private Sub ToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItem.Click
    If (Not Form1.Visible) Then
        Form1.Show(Me)
    End If
End Sub
 

Внутри Form1 есть Try блок. Если оно не передано, Form1 должно появиться окно сообщения перед закрытием. Появляется сообщение, но именно тогда я получаю сообщение об ошибке (в котором говорится Form1.Show(Me) )

 Private Sub Form1_Load(ByVal sender As System.Object, e As System.EventArgs) Handles MyBase.Load

        Try
            'DO STUFF
        Catch
            MsgBox("Error loading in data. Please contact an administrator")
            Me.Close()
            Return
        End Try

End Sub
 

Я совершенно новичок в этом типе программирования и изо всех сил пытаюсь решить проблему даже после поиска похожих проблем. Не мог бы кто-нибудь помочь или указать мне правильное направление?

РЕДАКТИРОВАТЬ: похоже, это связано с попыткой закрыть форму во время Load события. Итак, мой вопрос теперь в том, есть ли какие-либо простые альтернативы? Я нашел способы сделать это в C# , но не так много для vb.net

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

1. Не закрывайте форму в ее Load обработчике событий.

2. Вы знаете, как я должен это делать? Форма имеет поле со списком, которое заполняется в обработчике Load событий. Если этот процесс завершается с ошибкой, мне просто нужно закрыть форму или вообще остановить ее открытие.

3. Если операция завершается неудачно, установите флаг. Прочитайте этот флаг в обработчике Shown событий, отобразите сообщение и затем закройте форму. Если вы решили, что форма вообще не отображается, если операция с базой данных завершается неудачно, выполните операцию с базой данных вне формы. Вы могли бы создать класс, который пытается получить данные и отображает форму только в случае успеха, передавая данные в форму.

4. Вы можете обмануть, используя Me.BeginInvoke(Sub() Me.Close()) , но лучший вариант — не помещать логику «показа» в форму. Заранее определите логику, загружать форму или нет, сохраните несколько циклов процессора.

Ответ №1:

Вот один из вариантов:

 Private loadFailed As Boolean = False

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Try
        '...
    Catch ex As Exception
        loadFailed = True
    End Try
End Sub

Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
    If loadFailed Then
        MessageBox.Show("Load failed")
        Close()
    End If
End Sub
 

В этом случае форма будет отображаться с сообщением над ней, затем она закроется, когда сообщение будет отклонено. Вот вариант, который не будет отображать форму:

 Friend Module Form1Manager

    Public Sub ShowForm1(owner As Form)
        If Not Form1.Visible Then
            Try
                '...

                'Pass data to Form1 here.

                Form1.Show(owner)
            Catch ex As Exception
                MessageBox.Show("Load failed")
            End Try
        End If
    End Sub

End Module
 

и, чтобы использовать это:

 Private Sub ToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItem.Click
    Form1Manager.ShowForm1(Me)
End Sub