Use two forms having MDI container active - c#

I have a main form with a MDI container active as well as a childform with a MDI container active. I want child form with mdi container act as parent to another form while main form is a mdi parent to child form with mdi container. How can I achieve this. I tried with below code for both the case but it showed error stating " A form cannot be Mdi parent as well as Mdi Child"
enter code here myform.MdiParent = this;
myform.Show();

You cannot - the message is quite clear about that. It's simply a limitation of the system. MDI is very old, and hasn't been updated in quite a long time.
If you need some alternatives, you could look at making windows not top-level, for example. The windows behave a bit differently (both from MDI and normal windows), but depending on your actual needs, they might be sufficient (or even better than MDI in the first place).

Related

Bring to Front MDI Child in C#

I am new in using C# and its IDE, Visual Studio. I am now creating an internal frame embedded in a winform. I used MDI Child, setting my winform as MDI parent. The problem is that, whenever I run my MDI child inside the MDI client together with other components (panel, buttons, field, etc.), my MDI child appears behind those other components. Is there any way to bring my MDI child in front of all those components? If there is, please also help me how to set the MDI child location as it appears inside my winform. Your help will be very much appreciated. :)

Multiple forms or one form and add controls

I am creating a windows mobile application that has several different screens. At the bottom of each screen is a menu bar which the user can click on to navigate each screen.
My question is should I use a new form for each screen and clone the menu or use one form and have all the other screens as a control and add them to the main form?
Cheers
I'd vote for controls.
Both mechanisms can achieve the flow you want, and from a fundamental perspective neither is going to really be worse (as in load times, memory consumed, or what have you) so it's largely a personal style decision. Me, I use a UI framework that lends itself heavily to UserControls, so that's what I use.
Generally speaking, when I create an app I have a single parent/host form that has Workspaces where I put my Views. Thos Views are UserControls. Whether I use a tabbed workspace or a desk workspace, they still end up as Controls. The only reason I use more than one full-up Form is if I have a dialog (warnings, inputs, etc) where I will be doing a ShowDialog call.
Per this link, there is no MDI functionality in Windows Mobile.
In our application, we use different forms for each screen.
There are two ways to open up new windows:
formName.ShowDialog(): the new screen will be opened as a child of the other screen. In this case, you won't be able to access your parent form until the child is closed.
formName.Show(): the new screen will NOT be opened as a child of the other screen. Hence, you can access your parent even if the child is not closed.
You can use TabControl in single form with each tab having it's own controls. No need to add controls dynamically. And one single form. The way to achieve this is discussed in more detail in this answer.
Creating Wizards for Windows Forms in C#

Unruly Child Dialogue, C# .Net Winforms

I am using WinForms for a C# project and my main form has a simple button that uses ShowDialog(this) on a second form to show it.
Like this:
if (myParameterForm.ShowDialog(this) == DialogResult.OK)
{//stuff happens}
As per my requirements, when the child form is visible, you cannot access the parent form.
For the past year this child form has been the bane of my application as it mysteriously manages to hide behind its parent form from time to time. The reason this is such a big problem is because the software is designed to be used from a touchscreen kiosk, so the user only has access to a touch-screen, but the child form has locked input from any form but itself till it is acknowledged (closed with ok or cancel).
On load the child form uses "this.TopMost = true" just in case, I added this as an effort to fix my problem.
I use no other visualizing functions on the child form, the thread calling the form literally waits there till the form is closed.
Since the user has no access to a keyboard, or anything but a touchscreen I'm miffed as to how the child form manages to hide behind the parent form. I actually have been unable to replicate the behavior, and have only seen it as a result of responding to service requests.
I want to avoid using a timer to continually check if the form is TopMost because it just seems wrong. Should I reconsider? What event could possibly be occurring that is banishing my child form backstage?
I've tried using the search, but as far as I can tell I'm doing this correctly... Assuming that there is some sinister 3rd party application causing occasional hijinks, what is the best way to detect and rectify this situation automatically without throwing in a periodic check? I am not sure that the VisibleChanged event is what I'm looking for.
I can reproduce the behavior you are describing by minimizing the child window when it is displayed using ShowDialog. Is it possible that something is minimizing the child window? You could try disabling the control box for the child window to see if that helps. I would probably also set ShowInTaskbar to false for the child window (for usability reasons).
I would probably just implement the child form as a dynamically loaded user control instead. When you need it just load it on top of everything else. This way your main window is always in focus and the content you want to display is on top. this will obviously be a bit of work, but judging by the fact that this has been a problem for a year, you probably don't mind the work if it fixes the problem. There may be more intricacies that you'll have to deal with(i.e. having to make all other controls invisible until the child is done, etc.) but I think this is the easiest and most reliable fix.
In my experience TopMost windows and modal dialogs never behave very well ... as you can lock yourself out if a TopMost window happen to cover the modal dialog control. Are you applying TopMost to the main window anywhere in your code?

Menu shortcuts and MDI in Windows forms

After I modified my application to the MDI application (main form became an MDI container), all of the shortcuts, which were specified int the main menu of the original form, are no longer works. What can I do in order to "turn them on" again?
The only thing that comes to mind is that you need to set the mdiparent property of any child form before you show it. You could have missed this when you switched the main form over.

Any new hope? Making a window an MDI child

Got some C# forms/controls that can be called up either from a C# control on a Winform in a Winforms MDI app OR the same C# control used by a PowerBuilder MDI app via COM.
I've been using the WinAPI call SetParent to attach forms to the MDI.
It works (or seemed to) in both environments.
It lets the child window have its own WindowState (Normal, Maximised) instead of taking on that of the child windows already open (which was a real pain).
Say the control is called T. Code on control T calls up form D.
Control T is on form X.
Control T is also on form Y.
In .Net all is well, and form D stays within the MDI.
in PB:
Control T is on PB control PX.
Control T is also on PB control PY.
For PX all is well.
For PY, however, there is a problem - form D does not seem to become an MDI child - it can go outside the app and has a taskbar icon. I stress that this is using same objects as the ones that do work. The SetParent is literally the same line of code.
Further research has revealed that SetParent doesn't really work for proper MDI childing - but that's OK(ish) cos we don't need to merge menus etc.
Interestingly, have found that though SetParent seems to 'work', you don't get the handle back if you try GetParent...
Form form = new MyForm();
WindowsMessageHelper.SetParent(form.Handle, MDIParentHandle); //passed down
int parentHandle = WindowsMessageHelper.GetParent(form.Handle);
parentHandle will always be 0....
Is there any way of making form D behave under all circumstances? My own researches have not been promising. I don't really want to go back and rewrite my forms as controls and have PowerBuilder manage them - mainly becasue there can be multiple instances of each form and PowerBuilder would have to handle that (instead of the controller class/base class I've got doing it in the .net app).
Can I stress that there is NO problem within .Net, the problem only shows up in the PowerBuilder app
In the end, we found that the difference was that PB was doing the equivalent of setting .MDIParent for the control PX (the one where calling up form D worked) but not for PY.
Once that was sorted then we were then getting the correct MDIParent handle and all is now well.
Your child needs to be a System.Windows.Forms.Form, and set its MdiParent property to the MDI Patent window (not its Parent).
The container needs to also follow a few rules.
A read through the MDI instructions on MSDN may help further.
Option two: you may not be able to do this with a single control. Instad consider composition of the core implementation in two wrappers. The first wrapper acts as a WinForms MDI child, the second as a COM wrapper for use under whatever GUI framework PowerBuilder works.
If the only problem you haven't solved yet is GetParent doesn't work you might be able to live with it.
EDIT: but asker has more problems.
There are a number of API pokes that have to be each done in turn to make this work. You will have an easier time making this a user control and placing it on a native MDI parent when using it VIA a COM interface or on a .NET MDI child when placing it in a .NET MDI parent.
There are different base window procedures (DefWindowProc vs DefMdiChildProc) that have to be used here and to make this work you end up implementing DefMdiChildProc.
If you used .NET reflector, you might be able to find a way to cause System.Windows.Forms.Form to call DefMdiChildProc for you.

Categories