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 :-)
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
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'm new to windows application.can anybody help me.here is my doubt.im having one parent form and it has four menu items. when i click any of one menu item ,it should display another form within that parent form itself. how to do it?
Thanks in advance
According to details you ve provided it seems that you need to use MDI Forms concept in your app. It s very easy to learn and refer to the following links:
http://www.codeproject.com/KB/cs/mdiformstutorial.aspx
How to open a form within a form?
Just include the code in the 2nd link within your menuitem_Click event...
Hope this helps...
There are several ways you could do it.
One simple way for a newcomer is to add the form to the parent form in the designer. Set the visible Property to false (in the properties) so it will not be shown at first when your program is run.
Then you can set the visible property to true when you handle the menu item clicking.
There are code ways to do it too at runtime etc.
Hers an article with stuff about adding controls (and implicitly child forms) at runtime.
Inside your main form, add a panel and then use the below method to display the child form.
private void InitChildForm(Form childForm, Panel parent)
{
childForm.TopLevel = false;
childForm.Parent = parent;
childForm.Dock = DockStyle.Fill;
childForm.Show();
parent.Parent = this;
parent.Dock = DockStyle.Fill;
}
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.
In java swing I can insert panels into panels and so on, and not have to build a brand new window for every view of my applicaiton, or mess around removing and adding controls.
Theres a panel clas sin C# however I cant see any way of creating a 'panel form' or basically just a form in form designer thats a panel and its contents.
How do I do this then and work the way I did with java swing?
Usually i just dock different forms within eachother setting the IsMdiContainer Property to true on the parent window. Then i create subforms that i dock using the following function:
static class FormUtil
{
static public void showForm(Form sender, Control reciever)
{
sender.ControlBox = false;
sender.FormBorderStyle = FormBorderStyle.None;
sender.ShowInTaskbar = false;
sender.TopLevel = false;
sender.Visible = true;
sender.Dock = DockStyle.Fill;
reciever.Controls.Clear(); //clear panel first
reciever.Controls.Add(sender);
}
}
then whenever i need to dock a form inside a panel on the parents form i just do:
FormUtil.showForm(new SomeForm(), this.splitContainer1.Panel1);
This allows me to delegate some of the form creation to different designers. Works like a charm for me, love to hear if theres a better way of doing it.
Actually, you can use the panel control and set it's Dock property to Fill. That way, your panel will be the entire canvas of the form. Then, you can add child panels as needed either through code behind or through forms designer.
There's the concept of user controls which basicly provides you with a panel like designer surface , not to mention that you can create atomic forms (which can be reused) and register them as inheritable, that way you can provide inheritance too.