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

Posted

技术标签:

【中文标题】在运行时添加控件的最佳实践【英文标题】:Best practice for adding controls at run-time 【发布时间】:2010-11-01 12:36:38 【问题描述】:

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

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

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

我曾假设它们是相同的,这取决于个人喜好,但工作中有人提到第二种方法更糟糕,因为在处置表单时按钮不会被处置(假设没有添加任何事件处理程序并被保留)。

这对我来说没有多大意义,所以我在网上查了一下,但找不到任何可以说的方式。

有人知道答案或可以指出正确的方向吗?

【问题讨论】:

你的意思可能是 this.Controls.Add... 复制:***.com/questions/961554/… 【参考方案1】:

由于推测是浪费时间,我抓起我的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);
                
            
        
    

基于此代码,这些方法是等效的,这完全是一个偏好问题。

【讨论】:

哦。你打败我了!没有人应该没有反射器。 出于支持目的,.Parent 比 .ControlsAdd(); 更难阅读和解释; @RSolberg -- 我不同意 Controls.Add 更明确,但这不是提出的问题。问题是使用 .Parent 模式的 Dispose 是否会出现问题。根据实际代码,不会有。【参考方案2】:

如果您正在编写一个在其运行期间打开和关闭大量表单的应用程序,我可以看到按钮处理可能是一个问题。您需要确保手头有一些适当的处理代码,以确保应用程序不会占用太多内存。

除此之外,我喜欢第一个语句,因为它更清楚地解释了您的代码在做什么。您正在创建一个新按钮,并将其添加到页面上的现有控件中。您可以在调试/重构时直接阅读此内容并了解正在发生的事情。在第二组代码中,这有点模糊。如果您浏览了最初的按钮声明并看到 btn.Parent = 此语句,您可能会认为您正在将按钮重新分配给新表单或类似的东西。

听起来确实有点挑剔,但最近我一直在帮助一些同事,向他们展示我的一些代码,我发现虽然绝对有不止一种方法可以给猫剥皮,但有时有一种特定的剥皮方式可以更好地解释未来的事物。

【讨论】:

【参考方案3】:

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

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

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

我觉得这更容易阅读,你不必做任何家谱分析来弄清楚父母是谁......

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

*** 上也有类似的问题。

【讨论】:

【参考方案4】:

在第二种情况下,控件可能不会在表单释放时被释放(我不确定它是否释放),但无论如何它应该在下一轮垃圾收集中释放,因为不应该在处理表格后对其进行任何硬性引用。结果是,按钮是否与表单一起处理对于大多数应用程序来说都不是问题。在绝大多数使用表单的应用程序中,用户是瓶颈,因此在处理表单控件集合之前是否必须等待垃圾收集器的一到两次通过都不会影响您的设计决策。

话虽如此,我更喜欢

this.Controls.Add(btn);

因为它在语义上似乎更适合您实际所做的事情。我总是使用这种方法而不是设置 Control.Parent 属性。

【讨论】:

【参考方案5】:

这确实是一个品味问题。以下是在Control 上设置Parent 属性时发生的情况。此代码由 .NET Reflector 提供。

set

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

【讨论】:

【参考方案6】:

我认为两者的结果是一样的

【讨论】:

【参考方案7】:

我个人喜欢

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

因为它是更明确和可读的代码。

【讨论】:

以上是关于在运行时添加控件的最佳实践的主要内容,如果未能解决你的问题,请参考以下文章

启用缓存时模拟服务人员和 Apollo 客户端的最佳实践

编写聊天界面的最佳实践

XAML: 自定义控件中事件处理的最佳实践

在 Asp.Net 解决方案中集成 silverlight 控件的最佳实践

在 Rust 程序和嵌入式 WebAssembly 运行时之间进行通信的最佳实践是啥?

XAML: 自定义控件中事件处理的最佳实践