【问题标题】:ASP.NET UserControl inheritance - get derived class control from baseASP.NET UserControl 继承 - 从基类获取派生类控件
【发布时间】:2015-03-19 15:07:41
【问题描述】:

我有几个源自BaseCtrl 的用户控件。

BaseCtrl 没有.ascx 标记页面,而只有.cs 文件中的代码定义。

我确信所有明确派生自BaseCtrl 的控件都有一个ChildControl 实例,ID 为CC,在其.ascx 标记页面中定义。

我需要从BaseCtrl 代码中检索派生控件中存在的CC 实例。


Derived1.ascx

...
<uc1:ChildControl runat="server" ID="CC" />
...

Derived1.ascx.cs

public class Derived1 : BaseCtrl { ... }

Derived2.ascx

...
<uc1:ChildControl runat="server" ID="CC" />
...

Derived2.ascx.cs

public class Derived2 : BaseCtrl { ... }

BaseCtrl.cs

public class BaseCtrl : UserControl
{
    protected ChildControl DerivedCC
    {
        get { /* ??? */ }
    };
}

如何在BaseCtrlDerivedCC 属性中获取派生类的子控件实例?

是否可以在页面生命周期的任何时候获取,或者派生控件是否需要完全加载/初始化?

【问题讨论】:

    标签: c# asp.net inheritance webforms user-controls


    【解决方案1】:

    选项1:使用FindControl方法通过ID找到CC子控件:

    public class BaseCtrl : UserControl
    {   
        protected ChildControl DerivedCC
        {
            get { return (ChildControl)this.FindControl("CC"); }
        }
    }
    

    选项 2: 将名为 CC 的受保护字段添加到 BaseCtrl,并从每个派生用户控件的设计器文件中删除自动生成的 CC 字段:

    public class BaseCtrl : UserControl
    {   
        protected ChildControl CC;
    
        protected ChildControl DerivedCC
        {
            get { return this.CC; }
        }
    }
    

    (当然,您可能希望完全删除 DerivedCC 属性,因为它是多余的。)

    选项 3: 使 DerivedCC 成为 BaseCtrl 中的抽象属性,并在每个派生的用户控件中覆盖它:

    public abstract class BaseCtrl : UserControl
    {
        protected abstract ChildControl DerivedCC { get; }
    }
    
    public class Derived1 : BaseCtrl
    {
        protected override ChildControl DerivedCC
        {
            get { return this.CC; }
        }
    }
    
    // And similarly for Derived2.
    

    所有三个选项都允许您在页面生命周期的任何时候访问DerivedCC,除了在控件的构造函数中(此时属性将返回 null)。

    选项 1 的优点是它需要的代码更改量与您目前的相比最少。

    选项 2 的优点是它可以说比调用 FindControl 更简单、更干净。

    选项 3 的优点是它有助于验证在编译时您实际上在每个派生用户控件中都有一个CC 子控件。

    【讨论】:

    • 选项 1:注意 Findcontrol 不是递归的。 IE。如果 DerivedCC 的直接父控件不是 BaseCtrl,则 FindControl 将返回 null。
    • @Bombinosh:FindControl 递归的——只是不是通过命名容器。因此 FindControl 如果 CC 包含在 Panel 或 PlaceHolder 中,它将找到 CC,但如果它包含在 Repeater、UserControl 或其他任何实现 INamingContainer 的东西中,则不会。
    • 是的。我忘记了我主要使用模板化控件,因此需要递归实现 findcontrol。无论如何,让 OP 了解 INamingContainer 限制是件好事
    猜你喜欢
    • 2012-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-23
    • 2017-04-14
    • 2010-10-05
    相关资源
    最近更新 更多