ASP.NET UserControl 继承 - 从基派生 class 控件

ASP.NET UserControl inheritance - get derived class control from base

我有几个派生自 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 属性 中获取派生的 class 的子控件实例?

是否可以在页面生命周期中随时获取,或者派生控件是否需要完全loaded/initialized?

选项 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,除了在控件的构造函数中(此时 属性 将为 return null) .

选项 1 的优点是它需要对您当前拥有的代码进行最少的代码更改。

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

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