Try this code
Form1 form1 = new Form1();
//Subscribe event here
form1.MdiParent = this;
form1.Show();
This works for me
I don't know why your code doesn't work, I'll get back once I get the answer.
Edit: I have got the answer now.
ISynchronizationInvoke's
members (Invoke
and BeginInvoke
) are implemented by Control
class as follows.
- Gets context of Thread which created the window.
- Generate a new window messageId using
RegisterWindowMessage
- Encapsulate the delegate we passed as a parameter in
ThreadMethodEntry
add it into control's internalQueue
- Posts the message to thread's queue with messageId returned by
RegisterWindowMessage
usingPostMessage
- Handles
WndProc
listens formessageId
then De-queues theThreadMethodEntry
and invokes the delegate.
What goes wrong here?
Form1 form1 = new Form1(); form1.Show(); form1.MdiParent = this;
Form.Show
somehow results in a call to OnLoad
method, that is where OnShown
is called Asynchronously using BeginInvoke
if (base.IsHandleCreated)
{
base.BeginInvoke(new MethodInvoker(this.CallShownEvent));//reflected code
}
So before the posted WindowMessage
receives you set form1.MdiParent = this;
which in turn forces the control to Destroy
it's handle and ReCreate
new handle.
DestroyHandle
method swallows the posted message by getting it using PeekMessage
function, and then enumerates all elements in Queue
and sets its state as completed without invoking the delegate but marking it to throw ObjectDisposedException
.
Form1 form1 = new Form1();
form1.Show();
Action del = () =>
{
Console.WriteLine("This will never be called");//our custom delegates too fails to be invoked
};
var res = form1.BeginInvoke(del);
//after some more code
form1.EndInvoke(res);//throws `ObjectDisposedException` which was marked previously
form1.MdiParent = this;
throwing ObjectDisposedException("Control")
is actually misleading isn't it?
Note: You can fix this easily using Application.DoEvents();
before form1.MdiParent = this;
since DoEvents
process all the pending messages immediately.