Элементы управления очистки панели не могут вызывать события form.close (или) form.leave

Что я наделал:
У меня 3 Forms, в которых есть панель в Form_1 и 2 кнопки (button_1, button_2).

Событие щелчка button_1 добавляет Form_2 в панель. (раньше, если я очищу элементы управления Panel) Событие щелчка button_2 добавляет Form_3 в панель. (раньше, если я очищу элементы управления Panel)

Что я ищу:
В Form_2 и Form_3 у меня есть события Form.closing() и Form.Leave(), но эта функция не вызывается.

Я открыл последовательный порт в Form_2, он не закрывается должным образом.

Вот мой код:

public partial class Form_1 : Form
{
    public Form_1()
    {
        InitializeComponent();
    }

    private void button_1_Click(object sender, EventArgs e)
    {
        Form_2 ObjForm_2 = new Form_2();
        panelBody.Controls.Clear();
        panelBody.Refresh();

        if (ObjForm_2.IsDisposed)
        {
            ObjForm_2 = new Form_2();
        }
        ObjForm_2.TopLevel = false;
        ObjForm_2.FormBorderStyle = FormBorderStyle.None;
        ObjForm_2.Dock = DockStyle.Fill;
        panelBody.Controls.Add(ObjForm_2);
        ObjForm_2.Show();
    }

    private void button_1_Click(object sender, EventArgs e)
    {
        Form_3 ObjForm_3 = new Form_3();
        panelBody.Controls.Clear();
        panelBody.Refresh();

        if (ObjForm_3.IsDisposed)
        {
            ObjForm_3 = new Form_3();
        }
        ObjForm_3.TopLevel = false;
        ObjForm_3.FormBorderStyle = FormBorderStyle.None;
        ObjForm_3.Dock = DockStyle.Fill;
        panelBody.Controls.Add(ObjForm_3);
        ObjForm_3.Show();
    }
}

Каждый раз, когда вы хотите очистить существующую форму и добавить новую?

Baskar John 31.10.2018 12:20

поможет ли ответ прояснить проблему? Помогло потом пометить как Answer.

Baskar John 01.11.2018 07:41

Controls.Clear () - очень опасный метод с вводящим в заблуждение именем, он не избавляет от удаленных элементов управления. Вместо этого они размещаются в невидимом «парковочном окне», сохраняя свое вечное существование. Вместо этого вы должны использовать while (panelBody.Controls.Count > 0) panelBody.Controls[0].Dispose()

Hans Passant 01.11.2018 17:50

И будьте осторожны с SerialPort, требуется некоторое время после вызова его метода Close () или Dispose (), прежде чем порт снова сможет Open (). Рабочий поток должен выйти, сколько времени это займет, непредсказуемо. Значит, вы не хотите, чтобы он был членом вашего класса ObjForm_2.

Hans Passant 01.11.2018 17:53

@HansPassant, могу ли я использовать Thread.Sleep (1000) после закрытия последовательного порта. И даже открытие последовательного порта тоже занимает некоторое время.

P.G.Delhiganesh 03.11.2018 06:36
0
5
251
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы должны Close форму после удаления элементов управления с панели.

public partial class Form_1 : Form
{
    private Form frmChild;
    public Form_1()
    {
        InitializeComponent();
    }

    private void button_1_Click(object sender, EventArgs e)
    {

        if (frmChild != null)
        {
            frmChild.Close();
            frmChild.Dispose();
        }
        panelBody.Controls.Clear();

        frmChild = new Form_2();
        frmChild.TopLevel = false;
        frmChild.FormBorderStyle = FormBorderStyle.None;
        frmChild.Dock = DockStyle.Fill;
        panelBody.Controls.Add(frmChild);
        frmChild.Show();
    }

    private void button_1_Click(object sender, EventArgs e)
    {
        panelBody.Controls.Clear();

        if (frmChild != null)
        {
            frmChild.Close();
            frmChild.Dispose();
        }
        panelBody.Controls.Clear();

        frmChild = new Form_3();
        frmChild.TopLevel = false;
        frmChild.FormBorderStyle = FormBorderStyle.None;
        frmChild.Dock = DockStyle.Fill;
        panelBody.Controls.Add(frmChild);
        frmChild.Show();
    }
}

Благодаря JimifrmChild.Dispose() перемещен до panelBody.Controls.Clear(), подробности см. В комментариях.

frmChild.Close(); и frmChild.Dispose() до panelBody.Controls.Clear();. .Refresh() не требуется.
Jimi 31.10.2018 18:51

Спасибо, @Jimi. Зачем менять последовательность? Фактически, метод Clear в этом контексте не требуется. Почему, потому что управление будет удалено с Controlscollection, как только управление будет Disposed из памяти.

Baskar John 01.11.2018 07:38

Это разные вещи. Удаление объекта требуется, чтобы разрешить сборку мусора для неиспользуемой ссылки (особенно это необходимо, поскольку это форма). Controls.Clear() очищает лежащий в основе ControlCollectionа также его кеш. Control.Clear() - это просто петля while с .RemoveAt([Index]). Это не Dispose ничего. Но он очищает ArrangedElementCollection (связанный с макетом). .Net исходный код: Control.ControlCollection.Clear (). Используйте оба.

Jimi 01.11.2018 07:54

Спасибо @Jimi и благодарен вам. Да, проблема решена. Теперь вызывается событие Form.Close (), где я могу закрыть последовательный порт.

P.G.Delhiganesh 03.11.2018 06:29

Спасибо @Baskar John. Form.Close (), Form.Dispose (), Control.Clear () -> Этот порядок отлично работает. Как сказал Джими, Refresh () не нужен.

P.G.Delhiganesh 03.11.2018 06:34

Другие вопросы по теме