Правильное удаление / закрытие пользовательского элемента управления - PullRequest
2 голосов
/ 02 ноября 2011

У меня есть экран формы Windows с пристыкованной с левой стороны формы строкой меню, аналогичной Outlook 2003, и панель, занимающая оставшуюся часть правой части формы.

Мое левое меню содержит пункты.Нажав на эти элементы, я хочу загрузить соответствующий пользовательский элемент управления (действующий как «подформы») на правой боковой панели.Мне удалось это сделать, и он работает хорошо.

Хотя меня беспокоит то, правильно ли располагаются мои пользовательские элементы управления или они остаются в памяти, когда пользователь щелкает другой элемент меню (и как таковой)., загружает другой usercontrol / subform).

Код похож на этот:

    private void ultraExplorerBar1_ItemClick(object sender, Infragistics.Win.UltraWinExplorerBar.ItemEventArgs e)
    {
        panel1.Controls.Clear();

        if (e.Item.Key == "Action")
        {
            ActionUserControl subForm = new ActionUserControl();
            panel1.Controls.Add(subForm);
            subForm.Show();                
        }
        else if (e.Item.Key == "Options")
        {
            OptionsUserControl subForm = new OptionsUserControl();
            panel1.Controls.Add(subForm);
            subForm.Show();
        }
    }

Я не уверен, если Panel1.Controls.Clear () я звоню в началеэтого метода достаточно для того, чтобы пользовательские элементы управления больше не использовались для своевременного сбора мусора?

Насколько я понимаю, не должно быть никаких ссылок на него в приложении после его удаления из панели.но я не уверен, стоит ли мне делать что-то еще или использовать достаточно легкий инструмент, который я мог бы использовать для подтверждения того, что мои подчиненные формы расположены так, как они должны, и что это не вызывает какую-то утечку памяти / ресурсов?

Ответы [ 3 ]

6 голосов
/ 02 ноября 2011

Используйте этот цикл перед вызовом panel1.Controls.Clear() и убедитесь, что метод Dispose() в пользовательских элементах управления, в свою очередь, удаляет любые одноразовые ресурсы.

foreach (Control control in panel1.Controls)
{
   control.Dispose();
}
4 голосов
/ 28 декабря 2012

A для каждого цикла не будет делать работу. Так как после каждой утилизации элементы и индексы меняются.

Вам нужен цикл while, каждый раз выбравший самый верхний элемент управления.

В следующем коде, который я использую, у меня есть панель с пользовательскими элементами управления. Я вхожу в первый элемент управления и избавляюсь от его элементов управления, а затем избавляюсь от самого элемента управления.

После утилизации всех элементов управления вызвать сброс для сброса индекса.

While pnlMain.Controls.Count > 0

    While pnlMain.Controls(0).Controls.Count > 0
        pnlMain.Controls(0).Controls(0).Dispose()
    End While

    pnlMain.Controls(0).Dispose()
End While
pnlMain.Controls.Clear()
1 голос
/ 02 ноября 2011

Я делаю это достаточно с динамическим контентом, поэтому я добавил этот метод в свой класс базовой страницы:

/// <summary>
/// Dispose a control and all its children
/// </summary>
public void DisposeControl(Control c)
{
    if (null != c)
        using (c)
            DisposeChildControlsOf(c);
}

/// <summary>
/// Dispose (and remove) all the children of a control
/// </summary>
public void DisposeChildControlsOf(Control c)
{
    if (null != c)
        if (null != c.Controls)
            while (c.Controls.Count > 0)
            {
                Control child = c.Controls[0];
                c.Controls.RemoveAt(0);
                DisposeControl(child);
            }
}

Это тоже рекурсивно.И затем назовите это так (если вы не владеете элементом управления самостоятельно):

DisposeChildControlsOf(panel1);

или

DisposeControl(myDynamicallyGeneratedControl);
...