How to use MdiContainer - c#

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#

Related

Windows Forms Labels not showing before continuing

I'm building a simple Forms project. The method that loads the data takes a while to run, so I want the window to show that it is loading. There are some Labels that I Hide when the Form loads and then Show when the data is loading. However, for some reason I can't figure out, my Labels do not Show. The Buttons Hide properly, but the Labels do not Show before the data starts loading. Why is this? How do I fix it? I am looking for the simplest solution possible, please and thanks.
private void loadExistingButton_Click(object sender, EventArgs e)
{
loadExistingButton.Hide();
loadJsonButton.Hide();
this.Size = new Size(375, 179);
cardsLabel.Show();
loadingLabel.Show();
treeLabel.Show();
formattedLabel.Show();
loadFromExisting();
MainForm mainForm = new MainForm(startNode);
mainForm.FormClosed += (s, args) => this.Close();
this.Hide();
mainForm.ShowDialog();
}
private void StartForm_Load(object sender, EventArgs e)
{
cardsLabel.Hide();
loadingLabel.Hide();
treeLabel.Hide();
formattedLabel.Hide();
}
#Chetan 's suggestion is more suitable.
for example
//you can use this
cardsLabel.Visible = true;
//instead of
cardsLabel.Show();
//and you can use this
cardsLabel.Visible = false;
//instead of
cardsLabel.Hide();
Changing to directly setting Visible did not solve the problem, however calling Refresh() after Show did solve the problem. Thank you #Jimi for the solution!

C# Using One Panel As a Placeholder For Multiple Forms

I apologize if this has been addressed already, but I could not find a case that fit my exact situation. So here goes...
I have a MainForm that contains a toolStrip1 docked to the left that functions as a vertical navigation bar. I have a panel (pnlMain) filling up the remainder of the form. I want to use pnlMain to display different forms which are made up of win form classes. Right now, I can click on the labels/buttons on toolStrip1 to display different forms within pnlMain.
private void tsLblCustomers_Click(object sender, EventArgs e)
{
hidePanels();
CustomerReport cr = new CustomerReport();
cr.TopLevel = false;
cr.AutoScroll = true;
cr.BackColor = Color.White;
pnlMain.Controls.Add(cr);
cr.Show();
}
What I want to do now is display additional forms within pnlMain by clicking on a button on another form rather than a label/button on toolStrip1. Some of my forms are as follows: CustomerReport, AddCustomer, EmployeeReport, AddEmployee. The Report forms are linked to my tool strip buttons. The Add forms are linked to buttons on the Reports forms. I tried several things including the following:
1) On CustomerReport, I tried creating an instance of MainForm, then I'll create an instance of AddCustomer, and then add that instance to the panel on MainForm.
2) I also tried creating a method in MainForm to create the instance of AddCustomer, and then call that method from the Add button on CustomerReport. Even though the code was the same as the toolstrip buttons on MainForm, it did not work.
I tried different variations of hiding forms, showing forms, clearing the panel, setting Visible to true or false, and I can't get it to work right. In some cases, I've managed to hide the CustomerReport, but AddCustomer will not come up. At some point I think I created a NEW instance of MainForm and my code wasn't impacting the original form that is already open. I'm just lost. Should I be using a different design? Originally I set up my application to just hide one form then show the other but I read that that is a 'terrible design'.
This sounds very similar to this thread here: Creating Form Inside the Form
You'd want to look into MDI.
Although it sounds like you're aiming for one cohesive interactive window. Otherwise, if you just want separate windows to popup, you can create properties within that other form and read them after returning a DialogResult. I'm not sure why this would be bad design without knowing more about the context of the program.
//Optionally do a hide(); here.
AddCustomer customer = new AddCustomer();
DialogResult result = customer.ShowDialog();
if(result == DialogResult.OK)
{
var name = customer.Name;
//More properties or whatever here.
}
//The properties would still be accessible here, too.
I ended up keeping the toolstrip nav bar on the left side of the primary window, and I created a panel in the main part of the window. All forms are displayed in the panel. Each time one of the label options in the nav bar is clicked on, the current form is cleared off the panel and the active form is displayed.
private void tsLblCustomers_Click(object sender, EventArgs e)
{
pnlMain.Controls.Clear();
CustomerReport cr = new CustomerReport();
cr.TopLevel = false;
cr.AutoScroll = true;
cr.BackColor = Color.White;
pnlMain.Controls.Add(cr);
cr.Show();
}
private void tsLblEmployees_Click(object sender, EventArgs e)
{
pnlMain.Controls.Clear();
EmployeeReport emp = new EmployeeReport();
emp.TopLevel = false;
emp.AutoScroll = true;
emp.BackColor = Color.White;
pnlMain.Controls.Add(emp);
emp.Show();
}
private void tsLblVendors_Click(object sender, EventArgs e)
{
pnlMain.Controls.Clear();
VendorReport vend = new VendorReport();
vend.TopLevel = false;
vend.AutoScroll = true;
vend.BackColor = Color.White;
pnlMain.Controls.Add(vend);
vend.Show();
}
private void MainForm_Load(object sender, EventArgs e)
{
WelcomeForm welcome = new WelcomeForm();
welcome.TopLevel = false;
welcome.AutoScroll = true;
welcome.BackColor = Color.White;
pnlMain.Controls.Add(welcome);
welcome.Show();
}

Property or indexer 'Form.MdiChildren' cannot be assigned to -- it is read only

I keep getting the error in the title, and I can't figure out where the Form is set to read-only or how I can disable this.
private void studentToolStripMenuItem1_Click_1(object sender, EventArgs e)
{
addStudent newStudentForm = new addStudent(this);
newStudentForm.MdiChildren = this;
newStudentForm.Show();
}
addStudent is a form that takes care of creating students, and populating a list of students which is kept on the main form. So I want to be able to edit data on Form1 from Form2 which is why I am using Mdi
Can anyone give me any tips on where I should be looking at what I should be looking for to fix this error?
EDIT: To be clear
Form1 = Parent
Form2 = Child
MdiChildren is just an array, which represents the current forms, which are the Mdi Childs of the dialog. You need to load the MDI child into the parent.
Something like this:
addStudent newStudentForm = new addStudent();
newStudentForm.MdiParent = this;
newStudentForm.Show();
You don't need to set MdiChildren. Moreover, you wouldn't be able to set it this way even if it wasn't readonly - it is a collection of forms, not a form.
Logically, you try to tell that "newStudentForm has current form as MDI child", and is isn't true, you actually need "newStudentForm is a new MDI child of this".
The only thing you need to do is to set MdiParent in your child form:
private void studentToolStripMenuItem1_Click_1(object sender, EventArgs e)
{
AddStudent newStudentForm = new AddStudent(this);
newStudentForm.MdiParent = this;
newStudentForm.Show();
}
P.S. Please, use proper naming for your classes. It shuld be AddStudent, not addStudent. This one letter makes code absolutely unreadable.

Re-open child form

I have one Main form and two types of child form
MainForm
ChildFormA - unique
ChildFormB - have multiple forms of this type
I create ChildFormA with:
ChildFormA form1 = new ChildFormA();
form1.MdiParent = this;
form1.Show();
But when i close it with:
form1.Close();
I can't re-open it.
I've already read some tips that I can Hide this form instead or closing it. But the X button still closes the form.
How to re-open or how to prevent the X button to close and simple hide it?
If you want your child form to remain in its state, you have to subscribe to the FormClosing event and set the Cancel property of the event argument to true.
public ChildForm()
{
...
FormClosing += new FormClosingEventHandler(ChildForm_FormClosing);
}
void ChildForm_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
Hide();
}
Keep in mind, that you're form will not get disposed, if you don't add more logic to this.
Otherwise, you can just create a new instance of it.
Create a new instance of ChildFormA.
You should create a Child Form only Once .
ChildFormA form1 = new ChildFormA();
if(form1 == null)
{
form1.MdiParent = this;
form1.Show();
}
else
form1.Show();
than you should use Matthias Koch solution ,on child Forms
void FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
Hide();
}
Also Keep ChilFormA as a MDI Class Field ,so you won't lose Ref. to it.
to prevent the form from closing is described here. I would also advice hide, but maybe it works to set visible to false...
You could use the Singleton pattern in for this Form.
http://csharpindepth.com/Articles/General/Singleton.aspx
Look at the 4th approach
Then you would access it using the static instance instead of creating a new one.
You still need Matthias Koch solution ,on child Forms
void FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
Hide();
}
If you need further help with the Singleton pattern, please say so.

Cannot access a disposed object?

I have a countdown Timer form - on the first form the user will enter the countdown time - warning times, end message, etc. There are also two Radio buttons (Max/Min) and depending on which is selected they will open a new Max or Min form where the time will actually start to countdown. It is working fine and counting down as I expect. However, if I exit the Max or Min form and try to run again with new times I get the error. The code is below - note the comment out ShowDialog(this); was something I tried - it let me close and open the new forms ok but it did not actually start the countdown. UpdateLabels is the function that does the updating of Labels.
bool Max = rbMax.Checked;
if (Max == true)
{
//_Max.ShowDialog(this);
_Max.Show();
}
else
//_Min.ShowDialog(this);
_Min.Show();
UpdateLabels();
}
I also tried the following which I read online as a possible solution but it also did not work...
private void Max_FormClosing(object sender, FormClosingEventArgs e)
{
this.Hide();
this.Parent = null;
}
Can anyone help me out - I can post the UpdateLabels function if needed. I am pretty new to UI C# development so any help would be great. Thanks.
The problem is, that a closed form can not be used anymore (be reopened). Thats why the code you posted tries to stop closing and only hides your window. But for doing this, the Cancel-property must be set to true:
private void Max_FormClosing(object sender, FormClosingEventArgs e) {
this.Hide();
this.Parent = null;
e.Cancel=true;
}
To show the form after closing it this way, show it with the Show() method.
However this is probably only a workaround and you could solve the problem with another design.
Maybe it would be wise, to create a new instance of your form, every time you need it, instead of trying to reopen it every time. This also has the advantage that the form only requesires resources if it is really needed.
What you can do is add a following check before calling .Show method:
if(_Max == null || _Max.IsDisposed)
_Max = new MaxForm();
_Max.Show();
and similarly for _Min form
Whenever a form is closed, all its resources are freed. This means that you can't access the object any more, since it no longer exists - it's been freed and deleted from memory. To prevent that, you can cancel the closing of the form, and hide it instead (which will appear transparent to the user).
this.Hide();
e.Cancel=true;
An updated version of your code is as follows:
private void Max_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
this.Hide();
this.Parent = null;
}
The solution is simple that instantiate the object of the called form in the button click event e.g.
private void buttonSetting_Click( object sender, EventArgs e )
{
***_setting = new SettingWindow();*** //When I need to show the settings window
_setting.Show();
}
create new instatnce if object is not available
if(frmRGB==nullptr || frmRGB.IsDisposed==true )
{
frmRGB= new Form();
}
Create Object inside button click event
like this
private void btn_supplier_order_Click(object sender, EventArgs e)
{
form_supplier_order so = new form_supplier_order();
so.Show();
}

Categories