I'm following this tuto for create a multipage app in Winform. My MdiParent have
MainForm IsMdiParent = true
HomeForm frmHomeForm;
private void HomeIcon_Click(object sender, EventArgs e)
{
if(frmHomeForm == null)
{
frmHomeForm = new HomeForm();
frmHomeForm.MdiParent = this;
frmHomeForm.Show();
}
else
{
frmHomeForm.Activate();
}
}
If someone can help, it's first time I used MDI.
I was trying to show MdiChild on my MdiParent who was covered by another control. I remove the control on my MdiParent and my MdiChild now appear correctly in empty area.
In my current project. I click a button and the main form will set the ShowIcon false and the Visibility to false. Once I terminate the second window, I want to see the main form again. By resetting both properties to true. How is that possible?
As well where would I place the code.
Place this code in your button_click event:
newform nf = new newform(); //or whatever the name of your second form is
this.Hide(); //to hide your mainform
nf.ShowDialog();
this.Show(); //to show your mainform after closing your new form
nf.Dispose(); //optional
You can overRide the OnFormClossing event
protected override void OnFormClosing(FormClosingEventArgs e)
{
// code that u want
}
I would like to load multiple forms within a form using user controls and I've tried the following code but nothing seems to happen after clicking on button1. Anyone knows what's wrong?
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
UserControl1 control = new UserControl1();
control.Dock = DockStyle.Fill;
this.Controls.Add(control);
}
}
however the contents of UserControl1 seems to be overlapping and I can still see the content of Form1
The Z-order of the controls on the form matters. With Controls.Add(), the control ends up on the bottom of the order, existing controls overlap it. You fix it like this:
this.Controls.Add(control);
control.BringToFront();
Or use Controls.SetChildIndex() to insert it between controls.
Probably you need to change the value of Dock property. When it is DockStyle.Fill -- it will just take the whole area. Try to change it to other value, depending what layout you need.
This is what I usually do when I want to open a new form from a ToolStripMenu
private void alumnoToolStripMenuItem_Click(object sender, EventArgs e)
{
frmAlumno x = new frmAlumno();
x.ShowDialog();
}
but a teacher told me that it´s wrong because this shouldn´t happen..
So I guess I have to use MdiContainer but I´m not sure of how to write the code now... Please some help...
If you use MDI, you should call Show, not ShowDialog. Also you need to set MdiParent.
Form2 newMDIChild = new Form2();
// Set the Parent Form of the Child window.
newMDIChild.MdiParent = this;
// Display the new form.
newMDIChild.Show();
How to: Create MDI Child Forms
I'm going to answer with a solution to your actual problem instead of describing how to use MdiContainer, since you don't actually need it. :)
Forms have a ShowInTaskbar property that defaults to true. Set it to false and the form will no longer appear in the task bar.
private void alumnoToolStripMenuItem_Click(object sender, EventArgs e)
{
frmAlumno x = new frmAlumno();
x.ShowInTaskbar = false;
x.ShowDialog();
}
See MSDN for more information.
Introduction to MDI Forms with C#
Basically I am having two problems with C#.NET MDI. You can download VS2010 solution which reproduces bugs here.
1) When programmatically hiding and showing again a maximized child form, it is not maximized properly again and becomes neither maximized or in normal state.
childForm = new Form();
childForm.Text = "Child Form";
childForm.MdiParent = this;
...
private void showButton_Click(object sender, EventArgs e)
{
childForm.Visible = true;
}
...
private void hideButton_Click(object sender, EventArgs e)
{
childForm.Visible = false;
}
When child form is maximized, then programicaly hidden and shown again, it becomes something like this (please notice the menu bar - child form's control box appears, but child form is not maximized):
At this stage, child form cannot be moved around. However, I found a workaround for that, simply by showing and hiding a dummy child form, which forces the actual child form to become properly maximized. But this makes MDI area to flicker. Tried Invalidate, Refresh, Update methods, but they don't help. Maybe there are other workarounds to overcome this bug and not to make MDI area flicker with dummy child form?
private void workaround1Button_Click(object sender, EventArgs e)
{
dummyForm.Visible = true;
dummyForm.Visible = false;
}
2) When child form is maximized, the icon of the child form is displayed on menu bar. However, if you have to change the icon while the child form is maximized, the icon on the menu bar is not being refreshed (see the image above). I found a workaround for that too, which basically hides and shows menu bar. Icon gets refreshed, but it makes everything below menu bar to flicker. Tried Invalidate, Refresh, Update methods, but they don't help. Is there any other way to make menu bar to refresh the child form's icon?
private void workaround2Button_Click(object sender, EventArgs e)
{
menuStrip.Visible = false;
menuStrip.Visible = true;
}
Also I noticed that when parent form is in normal window state mode (not maximized) and you change the width or height of the form by 1 pixel, child form becomes maximized as it should be and child form's icon on menu bar gets refreshed properly and you don't need other workaround I described above. If I change the size of the form programicaly, form flickers by 1 pixel and I cannot do that, when parent form is maximized. Is there any way how I could invoke the repaint/refresh functionality which is called when you resize a form and which makes child form become maximized properly and the icon on the menu bar refreshed?
There's a bug in the implementation of the internal MdiControlStrip class, the control that displays the icon and the min/max/restore glyphs in the parent window. I haven't characterized it as yet, the code isn't that easy. A classic side effect of the bug is that the glyphs get doubled up, you found some other side-effects. The fix is simple though, delay creating the child windows until after the constructor is completed. Like this:
public MainForm()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e) {
childForm = new Form();
childForm.Text = "Child Form";
childForm.MdiParent = this;
dummyForm = new Form();
dummyForm.MdiParent = this;
dummyForm.WindowState = FormWindowState.Maximized;
base.OnLoad(e);
}
Have you tired using Hide/Show instead of setting visible to true/false?
Try:
private void showButton_Click(object sender, EventArgs e)
{
childForm.Show();
}
private void hideButton_Click(object sender, EventArgs e)
{
childForm.Hide();
}
How about this workaround?
private void showButton_Click(object sender, EventArgs e)
{
childForm.Visible = true;
childForm.WindowState = (FormWindowState)childForm.Tag;
}
private void hideButton_Click(object sender, EventArgs e)
{
childForm.Visible = false;
childForm.Tag = childForm.WindowState;
childForm.WindowState = FormWindowState.Normal;
}
UPDATE
I just gave you the idea how you could do. A better solution using the same idea as above would be a new base form which saves the windows state. See below. Derive your forms from FixedForm instead of Form:
public partial class FixedForm : Form
{
private FormWindowState lastWindowState;
public FixedForm()
{
InitializeComponent();
}
protected override void OnVisibleChanged(EventArgs e)
{
base.OnVisibleChanged(e);
if (Visible)
{
WindowState = lastWindowState;
}
else
{
lastWindowState = WindowState;
WindowState = FormWindowState.Normal;
}
}
}
Found a way how to come around those bugs.
First of all you need to suspend painting for a form and its children. I found a very helpful thread here, which describes how to do it.
After suspending painting, you need call UpdateBounds method of the control and increase ClientRectangle Width or Height by one and then decrease it back to the same value it was before. This invokes layout functionality which makes everything to update/repaint. Last step is to enable painting. Not very nice solution I guess, but it works.
StopDrawing();
UpdateBounds(Location.X, Location.Y, Width, Height, ClientRectangle.Width, ClientRectangle.Height + 1);
UpdateBounds(Location.X, Location.Y, Width, Height, ClientRectangle.Width, ClientRectangle.Height - 1);
StartDrawing();
I find suspending painting very helpful not only for working around those two bugs, but also in general to make GUI work more smoothly. I guess this can help to remove any kind of flickering. However, this solution requires P/Invokes, which should be avoided in general.
Why not just manually reset required icon in menuStrip items, after the creation of the window:
menuStripMain.Items[0].Image = null;