Дочерняя форма при закрытии не закрывается с первого раза

Дочерняя форма при закрытии не закрывается с первого раза.
После первого раза как нажмешь на крестик - если перечислять открытые формы, то дочерней формы нет, хотя она не мираж и функционирует в плане событий и методов.
Во второй раз если нажать на крестик - форма дочерняя закрывается.
При этом эта проблема исчезает если первое окно так закрыть один раз с таким глюком - то потом всё работает нормально.

Есть форма 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 шт):

Автор решения: Blackmeser

Самый простой и понятный вариант, пусть даже и не очень "правильный":

Во первых, описать вторую форму:

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); - тут по пунктам:

  1. tabPage?. - проверка, является ли tabPage=null, если не является - идёт дальше
  2. Parent?. - есть ли у него Parent (та же проверка на null), в нашем случае TabControl
  3. 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();

Нормально закрывается с первого раза.

→ Ссылка