Click here to Skip to main content
15,887,676 members
Please Sign up or sign in to vote.
3.50/5 (2 votes)
See more:
Dear all,

I'm trying to find a way of using an MDI Child (which happens to be a user control) within a TabControl on the MDI Parent. I am able to put several instances of the user control onto a tab using...

C#
Form NumForm = new NumericalViewer();
NumForm.TopLevel = false;
NumForm.MdiParent = this;           
NumForm.Show();
tc_main.SelectedTab.Controls.Add(NumForm);
NumForm.BringToFront();


The above snippet is called every time a button is pressed on the parent form to bring a new instance of the numerical viewer onto the screen. This control has a standard 'Sizeable' border.

When you add a new instance, its always the last one added whose border shows that instance has the focus. All the others become deselected. I can select any of the other instances, but they never show as though they have the focus. I've even tried adding this...

C#
protected override void DefWndProc(ref Message m)
{
    const long WM_NCLBUTTONDOWN = 0xA1;
    if (m.Msg == WM_NCLBUTTONDOWN)
    {
        this.Activate();
        datalist.Select();
    }
    base.DefWndProc(ref m);
}


(datalist being a control on the form) to recognise when a titlebar has been clicked on. This brings the instance to the front but does not appear to give it focus, and the titlebar stays the "unselected" colour.

In every other way, the code behaves as it should. Each instance has its own data it which it displays and updates as intended.

Are you allowed to drop MDI forms into container controls like this? Should I be looking at an alternative solution? Or am I just missing something really obvious.

I should add that I have looked at a number of the articles on codeproject associated with the TabControl and MDI - note here that I don't want each user control to be its own tab - I would like to have multiple instances of the control per tab - hope that's clear and makes sense.

Thanks for any advice and time you can give.

Aero
Posted
Comments
Sergey Alexandrovich Kryukov 30-May-12 20:27pm    
Why? why?!
--SA

Take a look at similar discussion: How to Open Child Window in tab[^]
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 31-May-12 20:17pm    
My 5. It has nothing to do with MDI, and confusingly, tabbed interface is sometimes called "tabbed MDI", because the tabs take over the role of MDI children, but they are not forms, which is good.
--SA
Maciej Los 1-Jun-12 2:12am    
Thank you, Sergey ;) I agree with you.
Here is the best way of using MDI child: never using MDI.

Here is the idea: who needs MDI, ever? Why torturing yourself and scaring off your users?
Do yourself a great favor: do not use MDI at all. You can do much easier to implement design without it, with much better quality. MDI is highly discouraged even by Microsoft, in fact, Microsoft dropped it out of WPF and will hardly support it. More importantly, you will scare off all your users if you use MDI. Just don't. I can explain what to do instead.

But first, look at what you are doing. The tab interface itself plays the role of the selector between different control containers, tabs. It is not designed to work with MDI, and MDI… is not designed to be hosted anywhere except intended relationship between MDI client (implemented by MDI Container) and MDI Children. You are trying to abuse something which is already a kind of abuse. :-)

Please see:
http://en.wikipedia.org/wiki/Multiple_document_interface#Disadvantages[^],
How to Create MDI Parent Window in WPF?[^].

And please also see my past answers explaining what to do:
Question on using MDI windows in WPF[^],
MDIContainer giving error[^],
How to set child forms maximized, last child form minimized[^].

Good luck,
—SA
 
Share this answer
 
v4
Comments
Aero72 31-May-12 4:22am    
SA - The reason for trying MDI is because it is actually what the user base for this kind of software is expecting (and I accept that doesn't necessarily mean its good for them) ;-)

I could just implement one instance of my user control per tab and have multiple tabs...or programmatically add a split container and allow several instances of it. However if I do that, the controls become docked - and again for this kind of software, the user is expecting to have floating controls to allow the user to set up their preferred screen (or screens - hence the tab control). My app already saves the size, location, user control type, what it contained and the tab page it was on so that the user can restore their last setup every time they run the software.

I have all this working quite well in "Non-MDI" mode with a couple of exceptions.

I tried using MDI because I know that an MDI interface has properties and methods associated with the Parent being able to know which child has the focus.

In Non-MDI mode, I can't find the right way to determine which of my user controls is being operated upon. At present the focus appears to be cycling round all of them - and that's the last thing I want. If anyone has any suggestions for this maybe I'll stop trying to use MDI!

Thanks and Regards, Aero
Sergey Alexandrovich Kryukov 31-May-12 17:28pm    
This is not what the users are expecting, this is what they may think they are expecting (which is also not fact), and by some reason this is what you think they are expecting. All those "user expectations" are often a myth, a result of reflection of the type "I think that you think that...".

Besides, going after the users is going nowhere. The success is only possible if the company or a person offers right things. Of course, it requires deep understanding of user interests, but this is not the same you think they think. This fallacy happens so many times so it became quite apparent to me.

You assumption about a focus is not quite correct. A focus is actually an attribute of the control (some are non-focusable though), is actually the keyboard focus (everything else is just a visual clue) and belongs to only one controls on the system. If has nothing to do with MDI. And you always know which control has focus. If not, ask about it (but better look at the documentation).

--SA
Maciej Los 31-May-12 17:29pm    
Here is the best way of using MDI child: never using MDI. - interesting advice ;)
+5 Sergey!
Sergey Alexandrovich Kryukov 31-May-12 20:13pm    
Interesting? At least, it works well!
Thank you, Maciej.
--SA
Maciej Los 1-Jun-12 2:11am    
"Interesting" - i forgot to add "" ;)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900