Making a Toolstripcontainer panel work like an MDI parent - c#

This is for C# and I am working in a Windows 7 environment with Visual Studio Express 2010.
I have an application where I have a toolstripcontainer dock set to fill so users can add toolstrips on any edge. The problem was that the toolstripcontainer has covered the that I want to use for holding sub-windows. The primary form containing the toolstripcontainer has been set as an mdi parent.
I found this article useful in getting the sub-windows into the container:
How to uses a ToolStripContainer whith Dock=Fill on a MDI parent?
However, sub-windows done in this way don't seem to behave as they should in the 'native' MDI environment. The boarders look as though the windows 7 Aero effect has been disabled and minimising the sub-window makes it disappear entirely.
Essentially I want an MDI area for sub-windows surrounded by toolstrip docking areas.
Thanks a lot for your help

Unfortunately, the ToolStripContainer control was not meant to work with an MDI form.
Try using the ToolStripPanel control instead. It doesn't work too well in the designer (which is probably why it isn't in the ToolBox by default).
Example:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
this.IsMdiContainer = true;
ToolStripPanel leftPanel = new ToolStripPanel() { Dock = DockStyle.Left };
ToolStripPanel topPanel = new ToolStripPanel() { Dock = DockStyle.Top };
this.Controls.Add(leftPanel);
this.Controls.Add(topPanel);
ToolStrip ts = new ToolStrip() { Dock = DockStyle.Fill };
ToolStripButton tsb = new ToolStripButton("Test", SystemIcons.Application.ToBitmap());
ts.Items.Add(tsb);
topPanel.Controls.Add(ts);
}
}

Related

Unable to display Child form on top of main form's controls

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

Panel changes it size in MdiContainer

We're running into a small problem here which really annoys us. Let me quickly explain what we're doing:
We're creating a Windows Form, save it as .DLL and load it a MDIContainer. Seems fine, works fine, except that, if we're using a Panel as component in our Form, it changes the size.
Before:
After (in MDIContainer):
(NOTE THE PANEL!).
We're guessing that it's because of our Custom MDI Container. This is the code of our MDI Container:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace NAMESPACE.Forms
{
class MdiClientPanel : Panel
{
private Form mdiForm;
private MdiClient ctlClient = new MdiClient();
public MdiClientPanel()
{
this.ctlClient.BackColor = Color.LightGray;
base.Controls.Add(this.ctlClient);
}
public Form MdiForm
{
get
{
if (this.mdiForm == null)
{
this.mdiForm = new Form();
System.Reflection.FieldInfo field = typeof(Form).GetField("ctlClient", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
field.SetValue(this.mdiForm, this.ctlClient);
}
return this.mdiForm;
}
}
}
}
Is there any way we can fix this? Thanks for helping.
//Edit:
Added bounty, because we want to know why this is so. How you can reproduce it:
Copy our MDIClientPanel code inside a new class in a new project
Create a second form, put some Controls inside it.
Load the form inside the MDIClient Panel.
Compile and look how the Size of the second form is changing.
This can be fixed if you open the second form like this:
SecondForm Form = new SecondForm();
Form.MdiParent = this.MdiClientPanel.mdiForm;
Form.Size.Width += 35; //THIS PART WILL FIX
Form.Size.Height += 20; //THIS PART WILL FIX IT
Form.Show();
But there is no way this is the only solution is it's kinda fishy...
The reason why this is happening, is because the boundries of the panel are not set.
You should be able to over come this by one of the following ways:
1 - Dock the panel;
var x = new MdiClientPanel{Dock = DockStyle.Fill};
Controls.Add(x); //Add the control to the form
2 - Anchor the panel to all corners;
x.Anchor = AnchorStyles.Top;
x.Anchor = AnchorStyles.Right;
x.Anchor = AnchorStyles.Left;
x.Anchor = AnchorStyles.Bottom;
I was able to reproduce this error and correct it using the above method(s).
Anchoring (before):
Anchoring (after - resizing parent):
Dock (before):
Dock (after - resize parent):
Hope this helps.
You have a fixed width and height at design time, it somehow does not follow your form to resize itself.
normally what we do is always to use a table layout panel (if there are more than one visible controls on the same form) and for each control, set the Dock to DockStyle.Fill. if there is only one control in the form, set the control itself to fill in to the form or the parent control (such as a tableLayoutPanel), and then set the following at either Design or behind-code:
pnl.Dock = DockStyle.Fill;
if you do want to leave some pace beside some controls, use TableLayoutPanel to have extra columns/rows with width (either fixed or in percentage). and then place the controls (like your panel) inside the cell you choose and set dockstyle to fill.
Consider anchoring the panel in your form. This will ensure that the panel will have equal space around it, regardless of the size of its parent form. Generally I prefer this over DockStyle.Fill.
When using the form as an MDI child, you really want to delegate control over its size to its MDI container. Just make sure your MDI child handles it nicely.

WinForms MdiContainer Menu

All, I have a WinForms MDI control and in it I dock several child windows. When I first did this I managed (somehow) to get rid of the window list (shown above the tabbed forms below)
I am not talking about the double window menu (on the right) I know that this is due to a bug in the WinForms control and that if you add MdiChild elements in the Load event instead of the Constructor, this behaviour resolves itsef (see this post for details).
Here I am talking about the menu strip itself, I don't want it! How do I get rid of it? Any advice is much appreciated...
Note: I am adding MdiChild forms in the following way:
foreach (Form mdiChild in MdiChildForms)
{
mdiChild.MdiParent = this;
mdiChild.Show();
}
where MdiChildForms is a List<Form>.
Here is the possible solution:
public MainForm() {
IsMdiContainer = true;
InitializeComponent();
this.MainMenuStrip = new MenuStrip(); // create our own menu strip
this.MainMenuStrip.Visible = false;
}

.NET MDI child form suppress/hide caption/icon area

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.

winforms panels vs java swing panels

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.

Categories

Resources