how to invoke an mdi form on a different form?

Joined
Mar 28, 2005
Messages
17
Programming Experience
Beginner
Hi everyone,

I have an mdi form which on load is going to load other mdi child forms as follows:


VB.NET:
...FrmMain_Load(object sender, System.EventArgs e)
{
   Form1 oForm1 = new Form1();
   oForm1.MdiParent = this;
   oForm1.Show();
 
   Form2 oForm2 = new Form2();
   oForm2.MdiParent = this;
   oForm2.Show();
}

however, the problem is that in the Load method of Form1 for eg... i am doing a lot of things and it takes some time to actually see the MdiParent form.

So how can i invoke this form1 on a separate thread please??? I want to first see the MdiParent load then see the child form loads...whereas now i have to wait for the MdiChild to finish processing then the MdiParent will load.

Please help.

Thanks,
Kevin
 
I believe that you should be able to achieve what you want by calling the Show method of the child form asynchronously.
VB.NET:
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim f As New Form2

        f.MdiParent = Me
        f.BeginInvoke(New MethodInvoker(AddressOf f.Show))
    End Sub
Note that this is a VB.NET-specific forum. Obvioulsy the .NET Framework is the same in both VB.NET and C#, but the languages are different. While I don't want to discourage you from asking your VB.NET-related questions here, if you want help with C# then you should find a C# forum.
 
Here is a way to do it. The main problem is how to change properties of objects the are created on different threads. Because the creation of mdi childs is on a seperate thread this cannot directly modify the mainform and its properties, to do this you have to make it threadsafe by using a delegate and invoke it from the mdi thread also passing relevant parameters, aka the mdi form object.
VB.NET:
Public Class Form1
Inherits System.Windows.Forms.Form
'...
 
Dim frm2, frm3, frm4 As Form2
 
Private Sub FormMain_Load(sender, e) Handles MyBase.Load
  Dim thr As New Threading.Thread(AddressOf addmoremdis)
  thr.Start()
End Sub
 
Sub addmoremdis()
  Dim dlg As New add_mdi(AddressOf addmdi)
  frm2 = New Form2
  Me.Invoke(dlg, New Object() {frm2})
  frm3 = New Form2
  Me.Invoke(dlg, New Object() {frm3})
  frm4 = New Form2
  Me.Invoke(dlg, New Object() {frm4})
End Sub
 
Delegate Sub add_mdi(ByVal frm As Form)
 
Sub addmdi(ByVal frm As Form)
  frm.MdiParent = Me
  frm.Show()
End Sub
 
End Class
You can check the InvokeRequired property of the control to be changed from a thread to see if a cross-thread operation could happen, if this is False you can modify that controls properties in the regular fashion. I don't check for this in the example because I know this is cross-threading.
 
thank you for replying so quickly ... i will try your recommendations tomorrow .... and sorry for posting the code in c#... but i write both vb and c# and i was just in a hurry ... thanks again!!!!
 
Hey guys,

i tired both suggestions and its like i'm almost there... now i can see the MdiParent frame ... and inside i see the child being loaded ... however, while the child form is loading... the MdiParent is still unresponsive.....hmmm i find this kind of surprising especially with the second suggestion where we used a different thread instead of an asynchronous call... any ideas how to not make the main MdiParent freeze while the child form is loading???/

many thanks again and god bless!!!

kevin
 
Try moving the initialization now in mdi form load to the Sub New constructor (after components are init'ed). Form load happens when a form is first showed (not when it is created), in this case through the delegate that makes a thread-safe attachment to FormMain. By moving inits to the contructor they will be called in the Sub addmoremdis that created the new mdi objects on the seperate thread (and before attaching to FormMain).
 
Hi john...thanks for your reply ... i had tried the initialization before and it just didn't work right for my application .. what i ended up doing was to start the child form regularly on the mdi parent .. .but in the child's form load .. i start a new thread using the ThreadPool class and the thread calls the method that does the long processing ... but when its done processing ... like grabbing all the data from the database... it calls another method to update my child form .. in this case, a datagrid ... but thanks to your help... i updated the child form asynchronously using .. Me.BeginInvoke(new MethodInvoker(...MyMethodToPoPulateGrid)) ...

... so the application now looks really neat... because the user can see the child form and the empty grid... the user can do other stuff ... and the child form populates the datagrid once the threat is done.... looks really cool already ... thanks again and have a good one!!!

kevin
 
Back
Top