So, i've been searching trough similar topics on stackoverflow and on other internet forums and knowledge bases but so far i had no luck trying to solve this problem i've been struggling for a whole week. Here is the code:
private void matrículasToolStripMenuItem_Click(object sender, EventArgs e)
{
Form1 form1 = new Form1();
form1.Show();
form1.MdiParent = this; // this == the main form of the aplication, wich has IsMdiParent property set to true.
}
If i take out the "form1.MdiParent = this", the shown event of form1 will fire normally, executing all of its handler's content, but if i let it there, shown event of form1 will not fire (i did set breakpoits, none of them triggered).
Curiously, if i use the Load event instead of Shown, everything works fine, but i'm a bit afraid if swapping Shown for Load would break something :(.
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.
RegisterWindowMessage
ThreadMethodEntry
add it into control's internal Queue
RegisterWindowMessage
using PostMessage
WndProc
listens for messageId
then De-queues the ThreadMethodEntry
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.