#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