Vb.net 调用表单showdialog不是模态的
我有两张表格,一张主表格和一张表格2。我试图将Form2显示为模态形式,并从MainForm显示背景。这是我到目前为止所拥有的 默认的MainForm出现,5秒后,它将从后台线程中以模态形式显示Form2。我关闭Form2,如果使用ShowDialog再次显示相同的Form2,则该表单不是模态的。如何确保显示的Form2始终是模态的Vb.net 调用表单showdialog不是模态的,vb.net,multithreading,invoke,Vb.net,Multithreading,Invoke,我有两张表格,一张主表格和一张表格2。我试图将Form2显示为模态形式,并从MainForm显示背景。这是我到目前为止所拥有的 默认的MainForm出现,5秒后,它将从后台线程中以模态形式显示Form2。我关闭Form2,如果使用ShowDialog再次显示相同的Form2,则该表单不是模态的。如何确保显示的Form2始终是模态的 Public Class MainForm Dim frm2 As Form2 Private Sub MainForm_Load(sender A
Public Class MainForm
Dim frm2 As Form2
Private Sub MainForm_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
frm2 = New Form2()
Dim frmHandle As IntPtr = frm2.Handle
frm2.Button1.Text = "test"
System.Threading.ThreadPool.QueueUserWorkItem(New System.Threading.WaitCallback(AddressOf DoSomething), 0)
End Sub
Private Sub DoSomething()
'call show dialog first time
Threading.Thread.Sleep(5000)
If frm2.InvokeRequired Then
frm2.Invoke(New Action(AddressOf frm2.ShowDialog))
Else
frm2.ShowDialog()
End If
'call show dialog second time
If frm2.InvokeRequired Then
frm2.Invoke(New Action(AddressOf frm2.ShowDialog))
Else
frm2.ShowDialog()
End If
End Sub
End Class
在showDialog中,可以设置使子窗体成为模态的父窗体:
Public Class MainForm
Dim frm2 As Form2
Private Sub MainForm_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
frm2 = New Form2()
Dim frmHandle As IntPtr = frm2.Handle
frm2.Button1.Text = "test"
System.Threading.ThreadPool.QueueUserWorkItem(New System.Threading.WaitCallback(AddressOf DoSomething), 0)
End Sub
Private Sub DoSomething()
Dim myAction as Action(Of System.Windows.Forms.IWin32Window)
'call show dialog first time
Threading.Thread.Sleep(5000)
If Me.InvokeRequired Then
myAction = AddressOf frm2.ShowDialog
Me.Invoke(myAction(Me))
Else
frm2.ShowDialog(Me)
End If
'call show dialog second time
If Me.InvokeRequired Then
myAction = AddressOf frm2.ShowDialog
Me.Invoke(myAction(Me))
Else
frm2.ShowDialog(Me)
End If
End Sub
End Class
您可以使用以下方法缩短代码:
New Action(Of System.Windows.Forms.IWin32Window)(AddressOf frm2.ShowDialog), Me)
最后一个frm2.ShowDialog(Me)返回一个错误。“跨线程操作无效:从创建控件“MainForm”的线程以外的其他线程访问该控件。”在最后一个
frm2.InvokeRequired
上,它是否返回true?最后一个frm2.InvokeRequired返回false。两个调用之间是否有代码?(在ShowDialog
s之间)基本上您需要frm2.invokererequired
返回true,并且仅当控件的句柄是在与调用线程不同的线程上创建时才会返回true(表示您必须通过invoke方法调用控件);否则为false。两个ShowDialogs之间没有代码。我提供的代码正是我编译的代码。第一个InvokeRequired结果为true,而第二个InvokeRequired结果为false。如何让InvokerRequired在第二次调用时返回true?在Load事件处理程序中访问frm2.Handle是一种随机攻击,目的是让它第一次工作。第二次就不行了。只是不要使用黑客使代码正常工作,您只需使用Me.Invoke()即可。