У меня есть контейнер MDI, а также я использую свой собственный класс MsgBox с именем ShowMsg, который я использую в основном в дочерних формах, пока он работал нормально, пока я не понял, что Showmsg (который является ShowDialog) не привязан к родительской форме ( MDIКонтейнер).
В дочерней форме я использую поток для запуска процесса и отображения индикатора выполнения, если пользователь переключается на другую программу с помощью alt+tab, пока процесс работает и завершается, когда пользователь возвращается в мое приложение с помощью Alt+Tab, ShowMsg там нет, он исчезает, и я ничего не могу сделать, чтобы вернуть его, поэтому мое приложение становится бесполезным.
Это происходит только при вызове из другого потока, чем сама форма, я рву на себе волосы, почему исчезает????
Это часть кода:
Public Function ShowMsg(ByVal Text As String, ByVal Icon As ShowMsgImage, ByVal Title As String) As DialogResult
Dim SMF As New ShowMsgForm
'Set the title bar
SMF.Text = Title
'Select an image and sound based on the Icon parameter
Select Case Icon
Case ShowMsgImage.Alert
SMF.MessagePictureBox.Image = My.Resources.ico_showmsg_Warning
SMF.Sound = Media.SystemSounds.Asterisk
Case ShowMsgImage.Confirm
SMF.MessagePictureBox.Image = My.Resources.ico_showmsg_Confirm
SMF.Sound = Media.SystemSounds.Question
Case ShowMsgImage.Critical
SMF.MessagePictureBox.Image = My.Resources.ico_showmsg_NotAllowed
SMF.Sound = Media.SystemSounds.Hand
Case ShowMsgImage.Info
SMF.MessagePictureBox.Image = My.Resources.ico_showmsg_Info
SMF.Sound = Media.SystemSounds.Asterisk
Case ShowMsgImage.Security
SMF.MessagePictureBox.Image = My.Resources.ico_showmsg_Lock
SMF.Sound = Media.SystemSounds.Beep
Case ShowMsgImage.UnderConstruction
SMF.MessagePictureBox.Image = My.Resources.ico_showmsg_NotAllowed
SMF.Sound = Media.SystemSounds.Asterisk
Case ShowMsgImage.Ok
SMF.MessagePictureBox.Image = My.Resources.ico_showmsg_ok
SMF.Sound = Media.SystemSounds.Asterisk
End Select
'Set other properties
SMF.TextLabel.Text = Text
SMF.QuestionTextLabel.Text = ""
SMF.Button1.Visible = True
SMF.Button1.Text = "OK"
SMF.Button1.DialogResult = DialogResult.OK
SMF.Button2.Visible = False
SMF.Button3.Visible = False
'Resize the form
SMF.SizeForm()
'Set its starting position
SMF.StartPosition = FormStartPosition.CenterScreen
'Display the form modally and return its DialogResult
Try
Return SMF.ShowDialog()
Catch ex As Exception
End Try
End Function
Образец на ребенке:
Private Sub btnGo_Click(sender As Object, e As EventArgs) Handles btnGo.Click
Dim backgroundThread As New Thread(AddressOf Processdata)
backgroundThread.Start()
End Sub
Sub ShowMsgDelegate(msg As String)
ShowMsg(msg, ShowMsgImage.Ok, "")
End Sub
Delegate Sub MyDelegate(ByVal msg As String)
Private Sub Processdata()
'Do stuff and when finished...
Me.Invoke(New MyDelegate(AddressOf ShowMsgDelegate), New Object() {"Done"})
End Sub
После нескольких дней и тестов я думаю, что нашел ответ.
Я добавил:
Параметр ParentForm
SMF.TopLevel = True
Return SMF.ShowDialog(**frm**)
Где frm — это форма, которая вызывает ShowMsg
LOL, я только что закончил тест и собирался предложить это. Проблема в том, что SMF
отстает от основной формы в z-порядке. Тем не менее, вы должны были видеть диалоговую форму при нажатии Alt-Tabbing и иметь возможность выбрать ее или выбрать ее на панели задач (по крайней мере, в Win 10).
Первое, что я бы сделал, это проверил идентификатор текущего потока в разных местах, чтобы убедиться, что код выполняется в потоке пользовательского интерфейса или вторичном потоке, как и ожидалось. На первый взгляд ваш код выглядит нормально, но он работает не так, как ожидалось, поэтому очевидно, что происходит что-то неочевидное, поэтому вам следует проверять вещи, которые кажутся очевидными, а не предполагать, что они есть.