Дочерняя форма при закрытии не закрывается с первого раза
Дочерняя форма при закрытии не закрывается с первого раза.
После первого раза как нажмешь на крестик - если перечислять открытые формы, то дочерней формы нет, хотя она не мираж и функционирует в плане событий и методов.
Во второй раз если нажать на крестик - форма дочерняя закрывается.
При этом эта проблема исчезает если первое окно так закрыть один раз с таким глюком - то потом всё работает нормально.
Есть форма Form1 (форма родитель для других окон) из неё при нажатии кнопки - создаю экземпляр Формы 2 (дочерняя форма):
Form2 frm2 = new Form2();
frm2.Show();
frm2.MdiParent = this;
tabControl1.TabPages.Add("Форма2");
//на форме 1 имеется tabcontrol куда добавляются вкладки с именами окон.
Далее к примеру я закрываю дочерний элемент форму 2, при этом делаю обработку события (после закрытия формы удаляю вкладку):
private void Form2_FormClosed(object sender, FormClosedEventArgs e)
{
for (int i = 0; i < Program.f1.tabControl1.TabPages.Count; i++)
{
if (Program.f1.tabControl1.TabPages[i].Text == "Форма2")
{
Program.f1.tabControl1.SelectTab(i);
Program.f1.tabControl1.TabPages.Remove(Program.f1.tabControl1.SelectedTab);
}
}
}
Ответы (1 шт):
Самый простой и понятный вариант, пусть даже и не очень "правильный":
Во первых, описать вторую форму:
class DaughterForm : Form
{
public TabPage tabPage; //тот самый TabPage который отвечает за форму
public DaughterForm()
{
this.FormClosed += closed; //дизайнер сам это делает, тут как пример
}
void closed(object sender, FormClosedEventArgs e)
{
tabPage?.Parent?.Controls.Remove(tabPage);
}
}
В ней сущности:
public TabPage tabPage //поле, который отвечает за связанную вкладку
void closed(object sender, FormClosedEventArgs e) //функция закрытия без всяких влезаний в родительскую форму (вообще лазать в родителя нельзя, только через методы, которые предоставил сам родитель, но этот вариант сложнее)
tabPage?.Parent?.Controls.Remove(tabPage); - тут по пунктам:
- tabPage?. - проверка, является ли tabPage=null, если не является - идёт дальше
- Parent?. - есть ли у него Parent (та же проверка на null), в нашем случае TabControl
- Controls.Remove(tabPage); - удаляем этот tabpage из родителя-контрола без всяких переборов (тут своё же правило нарушил), важно понимать, что если кто-то уже удалил tabPage или его там не было - будет ошибка, можно проверить наличие через Controls.Contains(tabPage)
Далее плодить формы с tabPage'ами:
DaughterForm daughterForm1 = new DaughterForm(); //создать форму1
daughterForm1.Text = "DaughterForm1"; //дать имя
TabPage tabPage1 = new TabPage(daughterForm1.Text); //создать вкладку1
daughterForm1.tabPage = tabPage1; //записать вкладку1 в форму1
tabControl.TabPages.Add(tabPage1); //добавить вкладку1 в список вкладок
daughterForm1.Show(); //показать форму1
//
DaughterForm daughterForm2 = new DaughterForm();
daughterForm2.Text = "DaughterForm2";
TabPage tabPage2 = new TabPage(daughterForm2.Text);
daughterForm2.tabPage = tabPage2;
tabControl.TabPages.Add(tabPage2);
daughterForm2.Show();
При закрытии дочерних форм вкладки будут удаляться сами, есть ещё минимум 5-10 вариантов, как сделать это более правильно, но они сложнее, зато дают возможности закрывать окно через вкладку, автоматически нумеровать окна/вкладки, автоматически создавать вкладки и помещать их в список вкладок, итд...
// Подправил с учётом MDI:
mainForm.IsMdiContainer = true;
DaughterForm daughterForm3 = new DaughterForm();
daughterForm3.BackColor = System.Drawing.Color.DarkGray;
daughterForm3.MdiParent = form;
daughterForm3.Text = "DaughterForm3";
TabPage tabPage3 = new TabPage(daughterForm3.Text);
daughterForm3.Parent = tabPage3;
daughterForm3.tabPage = tabPage3;
tabControl.TabPages.Add(tabPage3);
daughterForm3.Dock = DockStyle.Fill;
daughterForm3.Show();
Нормально закрывается с первого раза.