运行时添加控件的最佳实践

9

在运行时向表单添加控件时,您可以执行以下任一操作:

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

或者

Button x = new Button();
//...
btn.Parent = this;
我曾以为它们是一样的,只是个人喜好不同而已。但是有人在工作中提到第二种方法更糟,因为当窗体关闭时,按钮不会被处理(假设没有添加事件处理程序并且仍被保留)。这对我来说没有多大意义,所以我上网查找,但找不到任何可以证明哪个方法更好的信息。 请问有人知道答案或可以指点我正确的方向吗?

你可能指的是 this.Controls.Add... - Mehrdad Afshari
重复:https://dev59.com/gUfSa4cB1Zd3GeqPA-aX - RSolberg
7个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
12

既然猜测是浪费时间的事情,我拿出了我的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);
                }
            }
        }
    }

基于这段代码,这些方法是等效的,这仅仅是个人偏好的问题。


哦,你比我快!没有人应该没有反射器。 - PeterAllenWebb
3
为了支持目的,.Parent 比 .ControlsAdd() 更难阅读和解释。 - RSolberg
@RSolberg -- 我并不反对使用Controls.Add更明确,但这并不是提出的问题。问题是在使用.Parent模式时会有Dispose相关的问题吗?根据实际代码来看,不会存在任何问题。 - Jack Bolding

3

我一直更喜欢确定我要添加新控件的对象的控件...

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

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

我认为这种写法更易读,你不需要进行任何家谱分析来确定父元素是什么...

我相信在内部使用 .Parent 代码会执行 .Controls.Add,因此它们应该有相同的结果,但对我来说,这归结于代码可读性。

这里有一个类似的问题在StackOverflow上。


3
我能看到,如果你编写的应用程序在其持续时间内打开和关闭许多窗体,则按钮处理可能会成为问题。您需要确保有一些适当的处理代码,以确保应用程序不会吸收太多内存。 除此之外,我喜欢第一个语句,因为它更清楚地解释了你的代码在做什么。你正在创建一个新的按钮,并将其添加到页面上现有的控件中。在调试/重构时,您可以直接阅读并理解正在发生的事情。在第二组代码中,这略微模糊。如果你忽略了初始按钮声明并看到btn.Parent = this语句,你可能会认为你正在重新分配按钮给一个新的窗体或类似的东西。 听起来有点挑剔,但最近我一直在帮助一些同事展示我的代码,我发现虽然有超过一种方法来完成任务,但有时候有一种方式来完成任务,可以在未来更好地解释自己。

1
在第二种情况下,当窗体被释放时,控件可能不会被释放(我不确定是否会),但是它应该在下一轮垃圾回收中被释放,因为在窗体被释放后,它不应该有任何硬引用。总之,对于大多数应用程序来说,按钮是否随窗体一起被释放都不是问题。在使用窗体的绝大多数应用程序中,用户是瓶颈,因此在收集窗体控件之前等待一两次垃圾回收是否被释放,不应影响您的设计决策。 话虽如此,我更喜欢
this.Controls.Add(btn);

因为它在语义上更符合你实际正在做的事情。我总是使用这种方法,而不是设置 Control.Parent 属性。


0

这实际上是个品味问题。当你在一个Control上设置Parent属性时会发生什么,以下代码由.NET Reflector提供。

set
{
    if (this.parent != value)
    {
        if (value != null)
        {
            value.Controls.Add(this);
        }
        else
        {
            this.parent.Controls.Remove(this);
        }
    }
}

-1

我个人喜欢

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

因为这样的代码更加明确易读。


-1

我认为两者的结果是相同的


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,