Лучшая практика для добавления элементов управления во время выполнения - PullRequest
9 голосов
/ 09 июня 2009

При добавлении элементов управления в форму во время выполнения вы можете выполнить одно из следующих действий:

Button btn = new Button();
//...
this.Controls.Add(btn);

или

Button x = new Button();
//...
btn.Parent = this;

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

Для меня это не имело особого смысла, поэтому я заглянул в онлайн, но не смог найти ничего, что могло бы сказать так или иначе.

Кто-то знает ответ или может указать мне правильное направление?

Ответы [ 7 ]

12 голосов
/ 09 июня 2009

Поскольку спекуляция - пустая трата времени, я взял свой экземпляр Reflector и посмотрел на реальный код. Свойство Parent вызывает свойство ParentInternal, которое, в свою очередь, вызывает value.Controls.Add (this)

/* this code is part of the .NET Framework was decompiled by Reflector and is copyright Microsoft */
    internal virtual Control ParentInternal
    {
        get
        {
            return this.parent;
        }
        set
        {
            if (this.parent != value)
            {
                if (value != null)
                {
                    value.Controls.Add(this);
                }
                else
                {
                    this.parent.Controls.Remove(this);
                }
            }
        }
    }

На основании этого кода методы эквивалентны, и это строго вопрос предпочтения.

3 голосов
/ 09 июня 2009

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

Кроме того, мне нравится первое утверждение, потому что оно более четко объясняет, что делает ваш код. Вы создаете новую кнопку и добавляете ее к существующим элементам управления на странице. Вы можете прочитать сразу после этого при отладке / рефакторинге и понять, что происходит. Во второй группе кода это немного более расплывчато. Если вы отмахнулись от первоначального объявления кнопки и увидели btn.Parent = this, вы можете поверить, что вы переназначали кнопку на новую форму или что-то в этом роде.

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

3 голосов
/ 09 июня 2009

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

Button btn = new Button();
this.PlaceHolder1.Controls.Add(btn);

Button btn2 = new Button();
this.PlaceHolder2.Controls.Add(btn2);

Мне кажется, что это легче читать, и вам не нужно анализировать семейное древо, чтобы выяснить, кто является родителем ...

Я считаю, что внутреннее использование .Parent кода делает .Controls.Add таким образом, что они должны иметь тот же конечный результат, но для меня это сводится к читабельности кода.

Здесь есть похожий вопрос StackOverflow .

1 голос
/ 09 июня 2009

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

Учитывая сказанное, я предпочитаю

this.Controls.Add(btn);

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

0 голосов
/ 09 июня 2009

Это действительно вопрос вкуса. Вот что происходит, когда вы устанавливаете свойство Parent для Control. Этот код предоставлен .NET Reflector.

set
{
    if (this.parent != value)
    {
        if (value != null)
        {
            value.Controls.Add(this);
        }
        else
        {
            this.parent.Controls.Remove(this);
        }
    }
}
0 голосов
/ 09 июня 2009

лично мне нравится

Button btn = new Button();
//...
this.Controls.Add(btn);

Потому что это более понятный и читаемый код.

0 голосов
/ 09 июня 2009

Я думаю, что оба результата к одному и тому же

...