mzurita
mzurita

Reputation: 690

Show form as modal in a new thread

In vb.net, I have a winforms application which periodically launches a form to check several operations in a different thread of the main thread. I would like to show these forms in a "modal" way, so the thread access of the Main Form have to be locked.

Is it possible?

Is there another way to launch a form in a new thread without using Application.Run (new Form())…?

The code is as follows:

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

Upvotes: 0

Views: 6204

Answers (4)

Jas
Jas

Reputation: 71

You can make an application modal form from another thread by invoking to the Applications 'MainForm'. The "MainForm" can be found using Application.OpenForms[0] if it is not directly accessible.

Something like this

    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();
   }

Upvotes: 1

Matt Wilko
Matt Wilko

Reputation: 27342

You can open a form using ShowDialog, which will stop execution of the code in the thread until the from is closed, but it won't show on top of any other forms.

I think to do what you want you will have to specify the owner form so that your modal form is on top. The issue is that you will get a Cross-thread operation not valid error if you try and do this on a separate thread:

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

So you will have to use a Control.Invoke like this:

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

Upvotes: 0

Matze
Matze

Reputation: 5508

You can´t show a modal window from another thread, but you can show a window and make it always on top of other windows. This is because a modal window always needs an owner window... you probably know that a window has a handle, and such handles cannot be shared between threads. Since the main window handle belongs to main thread (usually the UI thread), showing a modal window from a separate thread is prohibited and will cause an exception.

Use something like this to show a new window...

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

Set the TopMost-property of the Form instance to true, to make the window stay always on top of others...

window.TopMost = True

You can also find an example for this in the MSDN: http://msdn.microsoft.com/de-de/library/system.windows.forms.form.topmost(v=vs.110).aspx

The Run method of the Application class is not the right way to show another form. It is there to start a message loop for the application; see: http://msdn.microsoft.com/de-de/library/ms157902(v=vs.110).aspx

Upvotes: 2

lsteinme
lsteinme

Reputation: 750

Another way would be to disable the main Window before opening the "modal"-Window and re-enable it after the modal is closed.

Upvotes: 0

Related Questions