3

(Revised for content quality)

We had built forms based application for a customer based on their requirements. Toward the end of the project, they decided they wanted the app to function as a part of another Winforms app in a way that required the screens to be contained within larger forms. They also wanted to dynamically load forms and other UI elements. I decided to try simply loading forms dynamically inside another form, at at the time, wasn't comfortable with changing over all of the forms to controls.

When I load a form dynamically inside another form or container control, the editing behavior of the inner form's components changes. Text editing, in a TextBox or ComboBox, does not allow me to select partial text with the mouse, though I can double click to select all the text in the control.

     FormChild form = new FormChild();
     form.TopLevel = false;
     form.Dock = DockStyle.Fill;
     Controls.Clear();
     Controls.Add(form);
     form.Show();

The controls work as expected when I show the form normally, using Show() or ShowDialog(), but not when nested.

Being a bit new to Winforms from years of MFC, we had experience embedding forms inside MFC controls using FormView without issues, so assumed it would work ok with Winforms. It didn't turn out that way.

SOLUTION: I should have used a User Control in the first place. I refactored every form in the app manually, created blank controls, cut and pasted the InitializeComponent() as well as the logic into a User Control. As for the dynamic components, nowadays I create them at runtime, or do them in IronPython. Four years later I'm looking back at this question, shaking my head at my rookie mistake.

In addition, I've found that controls inside dockable panels work well for the original scenario I was faced with. Specifically, I started using DevExpress' DocumentManager and DockPanel. My inexperience at the time with Winforms got us into trouble; I've left this question in case someone else makes the same mistake.

codenheim
  • 20,467
  • 1
  • 59
  • 80
  • 3
    maybe it's just me, but loading a form into a panel seems wierd...`Forms` in winforms are equivalent `windows` in many other systems. – µBio Aug 13 '10 at 22:29
  • +1: Agreed, I don't know the specifics of why it doesn't work but I'm sure there's a better way to achieve this without embedding a form within a panel. The form would generally always be the outer container. – Matt B Aug 13 '10 at 22:32
  • +1: Me too. I've never even considered anything like this. – bporter Aug 13 '10 at 22:34
  • If you don't mind me asking, what's the rationale for embedding a form within a panel? – Matt B Aug 13 '10 at 22:43
  • I've updated the question. It is no longer embedded inside a panel. – codenheim Aug 13 '10 at 22:48
  • 1
    What you are doing may not be strange in MFC, but it is in winforms. They are different. Forms usually have [minimize][maximize][close] along with the rest of the things associated with a Window. 'In any case, saying it is weird isn't a solution' ... which is why noone has posted an answer, just comments :) – µBio Aug 13 '10 at 22:53
  • @Lucas: I understand. I suppose these components would have been better designed as User controls instead of forms. I will see if converting one resolves the issue. – codenheim Aug 13 '10 at 22:58

3 Answers3

3

Is it possible to place all the functionality (including controls) in your form into a User Control? If you want this functionality in a separate form, drop the User Control into an empty form, if you want it as part of an existing form, drop it into that.

This isn't a solution to the problem as you presented it, but maybe this suggestion will help.

Jay Riggs
  • 53,046
  • 9
  • 139
  • 151
  • I had already designed all of the forms, then the customer requested I not show a new dialog, but to load it into a content area, so I went this route. I suppose it would be best to convert all of the forms to controls? – codenheim Aug 13 '10 at 22:56
  • 1
    I don't know how many forms you're dealing with or their order of complexity, but you might consider at least testing this by taking your simplist form and converting it to a UC. – Jay Riggs Aug 13 '10 at 23:05
  • Done. Converting one of them to a control resolved the issue. Thanks for the suggestion. Time to get converting... :) – codenheim Aug 13 '10 at 23:08
  • Alternative: [Make top form an MDIContainer](http://stackoverflow.com/a/6463927/199364) – ToolmakerSteve May 20 '17 at 15:37
2

Judging from what you have posted, you want to dynamically load some ui elements and only show them when all are done loading? I usually will do it with a `Panel' or user control

[not compile tested code]

Panel p = new Panel();
p.TopLevel = false;
p.Dock = DockStyle.Fill;
p.Controls.Add( button );
// etc
Controls.Clear();
Controls.Add(p);
µBio
  • 10,668
  • 6
  • 38
  • 56
  • Thanks. I think I should have used a User control instead of a Form in the first place. I had already coded the forms when the customer requested they be put inside a content area, so I took the first route that occured to me. I'm no WinForms guru, this is the first time I'd tried this in WinForms, though I still don't understand the reason for the behaviour. The forms otherwise function well. – codenheim Aug 13 '10 at 23:02
  • 1
    @mrjoltcola Ouch...hopefully not too many forms. You may be able to copy most of the code out of the *.designer.cs files – µBio Aug 13 '10 at 23:08
  • +1 thanks for the suggestion. Converting the forms to controls seem to be the best route now. – codenheim Aug 13 '10 at 23:08
1

In short, what you want is possible, just take a look here:

http://social.msdn.microsoft.com/Forums/en/winforms/thread/a5a5ace5-2f88-4ed3-b1e5-ec3500ce1df1

It's all a matter of importing SetParent and using it. There'll be some overhead -- you'll have to deal with size and location of the child location -- but not much of a deal in most scenarios.

Bruno Brant
  • 8,226
  • 7
  • 45
  • 90