浅谈ASP.NET复合控件技术

原创|其它|编辑:郝浩|2010-04-29 13:29:40.000|阅读 1030 次

概述:复合控件也称为组合控件,主要是吧一些现有完整功能组件组合起来,形成单一的功能主控件,并且有主控件统一控制接口,每个子空间不再独立提供接口,复合控件所公开的方法集和属性集通常由构成组件的方法和属性提供,并加入一些新成员。复合控件也可以出发自定义事件,还可以处理并激起子控件所引起的事件。本文主要谈ASP.NET复合控件技术,

# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>

  从实现方式来看,控件分为三个类型:

  1、基本自定义控件:不包括现有的子控件,此类控件一般所有标记毒药自己编码输出内容,包括所有的时间等。

  2、继承控件:继承于现有的空间,扩展或修改了现有控件的内容。

  3、复合控件:也称为组合控件,主要是吧一些现有完整功能组件组合起来,形成单一的功能主控件,并且有主控件统一控制接口,每个子空间不再独立提供接口,复合控件所公开的方法集和属性集通常由构成组件的方法和属性提供,并加入一些新成员。复合控件也可以出发自定义事件,还可以处理并激起子控件所引起的事件。

  通常情况下,复合控件类要派生自System.Web.UI.WebControls.CompositeControl类。在ASP.NET1.X环境下只能继承System.Web.UI.WebControl抽象类并自己实现System.Web.UI.INamingContainer接口来实现符合控件。然而,在ASP.NET下,复合控件类的基类则发生了变化。

  下面介绍一下CompositeControl类,其声名代码如下所示:

  public abstract class CompositeControl : WebControl, INamingContainer, ICompositeControlDesignerAccessor
{
   //......
}

  CompositeControl类是一个抽象类,该类可以为自定义控件提供命名容器和空间设计器,CompositeControl类继承自 WebControl基类,并且实现INamingContainer 和ICompositeControlDesignerAccessor接口。

  INamingContainer是一个没有方法的标记接口,当控件在实现INamingContainer时,页框架可在该控件下创建新的命名范围,因此能够确保子控件在控件的分层树种具有唯一的名称,当符合控件公开模板属性,提供数据绑定或需要传送事件到子控件shizhe一点事非常重要的,在控件中可以通过NamingContainer属性访问命名容器。

  ICompositeControlDesignerAccessor接口使复合控件设计器可以在设计时重新创建其关联控件的子控件,该接口包含一个需要实现的方法RecreateChildControls,该方法可以在设计时重现创建该控件的子控件。

  如果创建的是数据绑定复合控件,那么自定义控件类的基类应该是CompositeDataBoudControl

  下面讲解CompositeControl类比较常用的方法和属性

  CreateChildControls方法

  重写从Control继承的受保护的CreateChildControls方法,以创建子控件的实例,并将它们添加到Controls集合,此方法可能会在页面和控件的生命周期内反复调用。为避免控件重复,ChildControlsCreated属性通常设置为true。如果此属性返回true,则CreateChildControls方法会立即退出。

  ChildControlsCreated属性

  该属性的数据类型为bool,其用于获取一个值,该值指示是否已创建服务器控件的子控件。如果已创建子控件则该属性为true;否则为false。该属性主要是为了避免CreateChildControls方法重复创建控件。

  EnsureChildControls方法

  该方法用语确定服务器控件是否包含子控件。如果不包含,则创建子控件。该方法首先检查ChildControlCreated属性的当前值。如果此值为false,则调用CreateChildControl方法。当需要确保已创建子控件时,将调用该方法。大多数情况下,自定义服务器控件的开发人员无需重写此方法。

  RecreateChildControls方法

  重写ICompositeControlDesignerAccessor接口的RecreateChildControls方法,它的基类虚实现代码如下:

  protected virtual void RecreateChildControls()
{
  base.ChildControlsCreated = false;
  this.EnsureChildControls();
}

  其功能主要是间接调用了CreateChildControls方法。这样在设计模式下,就可以执行创建子控件的方法并呈现创建的子控件。

  如果从WebControl类继承创建控件,则一般还要实现Render方法,借助Render方法呈现控件。Render方法在设计模式和运行模式下都执行。

  Controls属性

  该属性的数据类型为ControlCollection,用语获取ControlCollection对象,此对象表示UI层次结构中指定服务器控件的子控件。其属性值指定服务器控件的子控件集合,可以直接通过索引访问Controls集合中的控件,当子控件比较多时,经常通过FindControl方法检索子控件。

  其属性源代码如下:

  public override ControlCollection Controls
  {
  get
  {
  this.EnsureChildControls();
  return base.Controls;
  }
  }
 

  HasControls方法

  该方法用于确定服务器控件是否包含任何子控件。如果空间包含其他控件,则返回值为true;否则返回值为false。由于该方法仅确定是否存在任何子控件,可以通过允许你避免不必要的Controls.Count属性调用来改进性能。调用此属性要求实例化ControlCollection对象。

  该方法从基类Control继承而来。

  HasEvents方法

  这是一个ASP.NET2.0已经支持的方法,用于返回一个值,该值指示是否为控件或任何子控件注册事件。如果注册事件,则返回值为true;否则为false。该方法也是从Control基类继承而来。

  FindControl方法

  该方法用于在当前的命名容器中搜索指定的服务器控件,其参数为要检索的控件ID.该方法也是从Control基类继承而来。

  复合控件实现举例

  设想一下由两个其他控件(label 和 textbox)的组合生成的迄今为止最简单(也是最常见)的控件。以下介绍了一种编写这种控件的可行方法。我们将其命名为 labeltextbox。具体代码如下:

  public class LabelTextBox : WebControl, INamingContainer
{
    public string Text
    {
        get
        {
            object o = ViewState["Text"];
            if (o == null)
                return String.Empty;
            return (string)o;
        }
        set { ViewState["Text"] = value; }
    }
    public string Title
    {
        get
        {
            object o = ViewState["Title"];
            if (o == null)
                return String.Empty;
            return (string)o;
        }
        set { ViewState["Title"] = value; }
    }
    protected override void CreateChildControls()
    {
        Controls.Clear();
        CreateControlHierarchy();
        ClearChildViewState();

    }
    protected virtual void CreateControlHierarchy()
    {
        TextBox t = new TextBox();
        Label l = new Label();
        t.Text = Text;
        l.Text = Title;
        Controls.Add(l);
        Controls.Add(t);
    }
}

 

  该控件具备两个公共属性(Text 和 title)以及一个呈现引擎。这两个属性保存在视图状态中,并分别表示 textbox 和 label 的内容。该控件对于 render 方法没有替换方法,并通过 createchildcontrols 替换方法来生成其自己的标记。createchildcontrols 的代码首先清除子控件的集合,然后为当前控件输出的构成控件生成控件树。createcontrolhierarchy 是一种特定于控件的方法,不要求必须标记为受保护和虚拟。但请注意,大多数自带复合控件(例如 datagrid)只是通过一个类似的虚拟方法来暴露用于生成控件树的逻辑。

  CreateControlHierarchy 方法会根据需要实例化多个构成组件,然后合成最终输出。完成之后,各控件将被添加到当前控件的 controls 集合。如果希望控件的输出结果是一个 HTML 表,则可以创建一个 table 控件,并相应添加含有各自内容的行和单元格。所有行、单元格和所含控件都是最外部表的子项。这时,您只需将 table 控件添加到 controls 集合中即可。在上述代码中,Label 和 TextBox 是 labeltextbox 控件的直接子项并直接添加到集合中。控件的呈现状态和运行状态都很正常。


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com

文章转载自:欧阳旻

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP