I have a subform (child) that I want to use in a number of parents. I'm not a professional developer (I'm an architect - I know, you can save all the jokes... :) - working solo at present). I've ended up using an MDI form with the subform as a child. I maximize the subform form and most things are fine except that although I've tried to disable all the various widgets (the subform in the designer shows NO caption/icon/button area), I get TWO icons on the left and TWO sets of buttons on the right - of which ONLY the restore button works. Either of the sets of buttons will work the one child form.
Is there any way around this? I want the subform to be "transparent" the the user - they shouldn't be aware there's a subform in use.
I've done a quick search and I'd already suppressed the actual caption as mentioned in another answer - to get the caption bar suppressed in the designer...
Is MDI the right technology, or is there a better way to have the same subform appear in multiple parent forms?
VS2008, C#, Windows 7
TIA,
Paolo
There's a WF bug that will double the glyphs if you create the MDI child form in the parent's constructor. Here's an example:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
this.IsMdiContainer = true;
var child = new Form();
child.MdiParent = this;
child.WindowState = FormWindowState.Maximized;
child.Show();
}
}
Move the child form creation code to the Load event to avoid this.
Related
Windows 7 pro 64 bit, VS2015 or VS2019
Hi,
I have a C# Win Form with many various controls.
I defined the main form as MDI parent and built an MDI child form with it's own controls, activated by a menue item in the main.
The child form builds nicely, but it is always displayed under the main form's many different controls.
I have tried many remedies, non of whch solved the problem.
I'v Set the child form as TopMost = true; TopLevel = true; each or all, for no avail.
Have moved from VS2015 to VS2019 community - Same.
I have been wasting hours to solve something that seems to be strightforward.
Can anyone help me out of this?
//In Main Form with menustrip, ComPortSetup is a standard winform class with some controls
private void portSetupToolStripMenuItem_Click(object sender, EventArgs e)
{
ComPortSetup comPortSetup = new ComPortSetup();
comPortSetup.MdiParent = this;
comPortSetup.TopMost = true;
comPortSetup.TopLevel = true; //Can not change programmatically
comPortSetup.Show();
}
That is how MDI works, there is no way around that.
All controls on the MDI Parent form will take away "client" space for the MDI child forms. And thus they will always be shown on top of any MDI Child form.
In other words, the MDI child forms can only use the space that is on the MDI Parent form that is not occupied already by other controls.
What you can do is put a panel on the MDI Parent form, and for example dock it to the left. Then put your "main" controls on that panel. The MDI Child forms will use whatever space is left on your MDI Parent form.
You could put a splitter control next to this panel so you can make it larger or smaller, or make it slidable so the panel comes forward when your mouse is near it, and hides itself again when the mouse is moving away from it.
Another approach you can try, is not making it MDI anymore and set the parent of the "child" forms yourself. But this will most likely cause other problems.
I would try the first approach, the panel on the mainform, docked to the left with a splitter control next to it.
I am not sure, but I believe that when using MDI forms, it is not expected that the parent has its own controls on the main form area, otherwise you will experience this exact problem.
So there are a couple of ways around this.
Firstly you can place a Panel on your parent form, and then your child can be added to the Panel.
This is now "proper" MDI control however, but it might allow you to achieve what you want.
ChildForm child = new ChildForm();
parentPanel.controls.add(child); //ParentPanel needs to already be on main form
Or the other method is to put your Parent Controls either on a MenuStrip (like MS Word) or you can use a Floating Dockable child form (think Visual Studio) which is then always visible.
If you want to do the latter, then I would suggest DockPanelSuite control to help you with this
https://github.com/dockpanelsuite/dockpanelsuite
I want to know how to open different forms with a single main parent form in Metro Framework UI similar to a Modern POS System. As far as I know, I haven't found anything remotely close to that in the internet and I'm also having trouble trying to figure it out in Metro. Also I'm not talking about MDI Forms
Here's an example: (not in Metro)
Modern POS Design (watch first few seconds of the vid)
I'm talking about a dashboard type of UI where you open different modules using buttons on the left side of the Main form and the modules are opened as a child form in the Main form.
It has so many bugs when it comes to that kind of procedure. You can just use a simple form rather that MetroForm because MetroForm creates a somewhat black form on your screen when calling as child form. I don't know if it just in my application but it is really annoying.
You can just add your other forms to a panel at your main form.
There are many tutorials on how to do this but i will give you an example.
I created a method something like this in my utilclass:
public static Form NewForm(Form myForm, Panel myPanel)
{
myForm.TopLevel = false;
myForm.AutoScroll = true;
myForm.Dock = DockStyle.Fill;
myPanel.Controls.Clear();
myPanel.Controls.Add(myForm);
myForm.Show();
return myForm;
}
then calling from Main form to a panel:
Form2 myForm2 = new Form2();
UtilClass.NewForm(myForm2 , [YourMainFormPanel]);
I know this code is not the best approach but I'm just giving you ideas.
How can I show topmost a button clicked child form in my parent form (with a tabcontrol which docked as fill)?
It always shows the form at the back of the tabcontrol of the parent form, I've even used:
frm.TopMost = true;
frm.BringToFront();
Still shows at the back.
What you want is not possible. MDI children of a control get shown on a control (which you can't directly select) called MdiClient, which is not transparent (and can't be) and by default, goes always to the back of other controls in the parent form.
So the only way to do this, would be getting the MdiClient over the controls in the parent form: this would do what you expect, but it would also hide the parent controls when there are no child forms displayed (since again, the MdiClient is not, and can't be transparent).
So the only reasonable way would be having a maximized child form with the TabControl, instead of having that TabControl directly on the parent.
Or you could have your TabControl only shown when there are no child windows. For that, make a timer in the parent form, and check this at every interval:
if(MdiChildren.Length > 0)
myTabControl.SendToBack();
else
myTabControl.SendToFront();
This will only work if the MDI children are always maximized: your TabControl will not be visible when there are any children (no matter if they cover it or not)
Update
As remarked in the comments, you can have "your own MDI", by having a host control (a Panel, for example) in the parent form and loading the child forms in that control:
var form = new ChildForm();
form.TopLevel = false;
form.Parent = myHostPanel;
form.Show();
This would show the form inside the panel (which you can locate and zorder where you want)... you lose all the MDI management though, and you'll have to keep track of your children (and take care of the forms' events if needed) yourself.
I'd not use this solution, it's pretty hacky and can get messy for big applications (unless you do a correct system)
As a summary
Since we're discussing these methods in the comments
You can hack your way to do what you want, but you'll come into all sorts of problems with any approach.
If I was you, I'd redesign my application so that what you want to achieve is not needed. If you can't do that, the only sane way would be just not having those controls in the parent form, have an always-maximized, non-closable MDI child form with those controls, and skip that window everytime you need to work in the MDI children collection.
Please explain what components of what frameworks you are using and what you have done so far. Without that information i suggest the following solution (untested).
In the "ButtonClick" event of your ParentForm do this:
ChildForm cf = new ChildForm();
cf.MdiParent = this;
cf.Show();
If this doesn't work you may add a
cf.Focus();
This question make me uncomfortable :). after a lot of testing, I can't really find a solution. neither BringToFront() Function nor SendToBack() Work Properly. maybe the following approach can help you. I use IntersectWith Function of Rectangle Class and test if form intersect with tabControl or not. if so change the tab control visibility to false otherwise true. take a look at the following code:
first make form declaration public at the mdi parent form:
public partial class MdiParentForm : Form
{
Form frm = new Form();
}
After that when you initialize your child form, add some handler to its locationChanged event, like this:
frm.MdiParent = this;
frm.LocationChanged += Frm_LocationChanged;
frm.Show();
And at the end, This is the handler:
private void Frm_LocationChanged(object sender, EventArgs e)
{
Rectangle tabControlRectangle = new Rectangle(tabControl1.Location, tabControl1.Size);
Rectangle childFormRectangle = new Rectangle(frm.Location, frm.Size);
if (tabControlRectangle.IntersectsWith(childFormRectangle))
{
tabControl1.Visible = false;
}
else
{
tabControl1.Visible = true;
}
}
Thanks to #Jcl, Problem with this is that the tab control will hide and show as long as any point of the child form touches its rectangle. Moving the child form around would be horrible :-)
In Form1 I'm enabling IsMdiContainer and I added a MenuStrip. In Form1_Load I "new" Form2 and I'm assiging Form2.MdiParent to this which is Form1. I'm also maximizing Form2 and this operation works well.
In Form2 I have a treeView on the left side of the form and on the right side of the form I would like to display a number of different forms with various editing capabilities which will be dependent upon the node or level selected in the treeView.
I would like to create a number of different forms for editing data that would be displayed in Form2 depending on the selection from the treeView. I can't seem to add a form to the MdiChild and I've been seeing some posts where adding a form to a form may create some programming problems which I'm not sure about.
I really don't have any code to paste into this post because nothing seemed to work except for the Mdi Parent and Child relationship which was pretty simple.
Thanks in advance for any help.
There is a lot of information on this subject, but some documentation can be difficult to understand for some new developers. Follow these steps:
Open Visual Studio
Create a Windows Form Application
Click your Form
Go to Properties for that Form
Minimum Size : 1366 pixels by 768 pixels.
Launch Maximized
The important element is IsMdiContainer
Open your Toolbox.
Go to Menus
Drag FileMenu onto your Form
Build your Menu
Then go to Solution Explorer
Right-Click Add Item
Add another Form
I left mine as Form2 (In a real program, not a good name).
So within those fifteen steps, we have all that we need to accomplish our goal. So what we will do to finish our task is:
Go back to our First Form
Go to our FileMenu
Double Click on the menu button you wish to link.
It will load a code view, inside the area put this:
Form2 newFrm = new Form2();
newFrm.MdiParent = this;
newFrm.Show();
What this code is doing is three distinct things:
Line 1: It is actually calling our object, in this case a second form. It is actually building our object for us.
Line 2: Is actually linking our second form to our current form, this is physically turning our second form into a Child Form.
Line 3: This is actually physically showing our second form when the button is clicked.
That is all you need to physically show a Form.
In regards to your second question, I'm not entirely sure what your attempting to accomplish. It sounds like your trying to have a tree, then as a Node is selected the right hand side of the Form changes to specific context.
Now this isn't the nicest example, but do you mean something like this?
TreeNode node = treeView1.SelectedNode;
if (node.Text.Contains("XP"))
{
TextBox one = new TextBox();
Panel i = new Panel();
i.Dock = DockStyle.Right;
i.BackColor = Color.Black;
i.Controls.Add(one);
i.Show();
TreeFrm.ActiveForm.Controls.Add(i);
}
Not sure if that is what you are seeking. Obviously you'd want to implement a FlowLayoutPanel to make the positioning not a pain for you. Keep in mind an MDI Parent, with a Child Form acting as a MDI Parent will not work very well. As most things will default to MDI Parent Forms Docking / Positioning. This example is not pretty, but I'm not entirely sure of what your asking.
Are you trying to dock other forms or components on the same form?
I have found the Form.TopMost property but it puts the form on top of everything, including stuff that isn't part of my app. I've got a suspicion that I'm missing something obvious here. (Is Form the proper bases class for a non modal dialog box?)
Use the Form.Owner property of your dialog form and set it to the main Form.
Read more here
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.owner.aspx
The Owned form will never be displayed behind the Owner Form.
It is very simple; You just have to pass the owner when you call the Show() method
YourForm.Show(parentForm);
You can specify parent-child relationships between windows by supplying the parent Form as parameter to the ShowDialog() method called on the child Form. The child window will then stay on top of the parent and also minimize and restore along with the parent.
If i understand you correctly your opening a form from your application, and you want your new form to be on top of the old one.
To do this you can use ShowDialog() and StartPosition
SomeForm MyNewForm = new SomeForm();
MyNewForm.ShowDialog();
this will make that form stay on top of the orignal one, and you can also use
MyNewForm .StartPosition = FormStartPosition.CenterParent;
To control where that new form shows on the screen.