Reputation: 690
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
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
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
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
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