Vb.net 调用表单showdialog不是模态的

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

我有两张表格,一张主表格和一张表格2。我试图将Form2显示为模态形式,并从MainForm显示背景。这是我到目前为止所拥有的

默认的MainForm出现,5秒后,它将从后台线程中以模态形式显示Form2。我关闭Form2,如果使用ShowDialog再次显示相同的Form2,则该表单不是模态的。如何确保显示的Form2始终是模态的

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()即可。