在新线程中将表单显示为模态

问题描述 投票:0回答:4

在vb.net中,我有一个winforms应用程序,它会定期启动一个窗体来检查主线程不同线程中的几种操作。我想以“模式”方式显示这些表单,因此必须锁定主表单的线程访问。

有可能吗?

还有另一种方法可以在不使用Application.Run(new Form())的情况下在新线程中启动表单吗?

代码如下:

Imports System
Imports System.Windows.Forms

Friend NotInheritable Class Program

Private Sub New()
End Sub

<STAThread() _
Shared Sub Main()
    Application.EnableVisualStyles()
    Application.SetCompatibleTextRenderingDefault(false)

    threadFormCheckOperations.Start()

    Application.Run(New FormMain())

End Sub

Public Shared threadFormCheckOperations As New Thread(AddressOf launchThreadFrmCheckOperations)

Public Shared Sub launchThreadFrmCheckOperations()
    While(True)
         Dim threadForm As New Thread(AddressOf launchFrmCheckOperations)
         threadForm.Start()
         threadForm.Join() '---> Wait until thread is closed
         Thread.Sleep(60000)
     End While
End Sub

Public Shared Sub launchFrmCheckOperations()
    'I guess, here is where the code have to change… or is in the FormCheckOperations properties?
    Application.Run(New FormCheckOperations()
End Sub


End Class
.net vb.net multithreading modal-dialog .net-4.5
4个回答
1
投票

您不能显示另一个线程的模式窗口,但是可以显示一个窗口并使它始终位于其他窗口之上。这是因为模态窗口始终需要一个所有者窗口……您可能知道一个窗口具有一个句柄,并且这些句柄不能在线程之间共享。由于主窗口句柄属于主线程(通常是UI线程),因此禁止从单独的线程显示模式窗口,这将导致异常。

使用类似的东西显示一个新窗口...

Dim window As New FormCheckOperations()
window.Show()

TopMost实例的Form属性设置为true,以使窗口始终位于其他对象的顶部...

window.TopMost = True

您还可以在MSDN中找到一个示例:http://msdn.microsoft.com/de-de/library/system.windows.forms.form.topmost(v=vs.110).aspx

Run类的Application方法不是显示另一种形式的正确方法。它可以启动应用程序的消息循环。参见:http://msdn.microsoft.com/de-de/library/ms157902(v=vs.110).aspx


0
投票

另一种方法是在打开“模态”窗口之前禁用主窗口,并在模态关闭后重新启用它。


0
投票

您可以使用ShowDialog打开一个表单,它将停止线程中代码的执行,直到关闭from为止,但它不会显示在任何其他表单之上。

我想做您想做的事,您必须指定所有者表单,以便您的模式表单位于最前面。问题是,如果尝试在单独的线程上执行此操作,则会出现Cross-thread operation not valid错误:

frmModal.ShowDialog(frmMain) '< errors when run on a separate thread

因此,您将必须像这样使用Control.Invoke

Private Sub ShowModalForm()
    If Me.InvokeRequired Then
        Me.BeginInvoke(New Action(AddressOf ShowModalForm))
    Else
        frmModal.ShowDialog(frmMain)
    End If
End Sub

0
投票

您可以通过调用应用程序'MainForm',从另一个线程制作应用程序模式形式。如果无法直接访问“ MainForm”,则可以使用Application.OpenForms [0]来找到它。

这样的东西

    private DialogResult CallModalForm()
    {
        Form mainform = null;
        if (Application.OpenForms.Count > 0)
            mainform = Application.OpenForms[0];

        if(mainform != null && mainform.InvokeRequired)
            return (DialogResult) mainform.Invoke(new Func<DialogResult>(CallModalForm)) ;

        MyModalform form = new MyModalform ();
        form.TopMost = true;
        return form.ShowDialog();
   }
© www.soinside.com 2019 - 2024. All rights reserved.