原创  模板化控件 收藏

我对模板化控件的理解:

  • 模板化控件是一种复合控件
  • 模板属性的作用是提供一个实际的子控件将内容显示出来
  • 模板容器内存放着要显示的实际内容.
  • 模板容器可从任何可以作为适当的容器的控件派生. 
  • 模板属性和模板容器的关联由模板属性的TemplateContainer元数据属性描述.如: TemplateContainer(typeof(ContactPanel))
  • 模板的 InstantiateIn 方法就是将模板容器内的内容放到模板中显示出来
  • 模板的 InstantiateIn 方法把用模板表示的子控件添加到容器实例 
  • 如果要重复的实例化控件中的模板,模板容器应该实现 INamingContainer 接口.
  • 如果要重复的实例化控件中的模板,必须对模板中定义的子控件的 DataBinding 事件进行处理.
  • 如果要重复的实例化控件中的模板,模板不应该包含任何控件实例作为成员变量 
  • 在CreatChildControls方法中将模板加入到控件树中

有关模板控件的一点认识 :

创建一个简单的完整模板服务器控件步骤:
1、定义要和模板控件类一起使用的容器类。
2、用ParseChilden特性标记控件类,使模板属性中的Html元素能被页面分析器解析;
3、为每个定义的模板呈现ITemplate类型公有属性;
4、用TemplateContainer特性装饰模板属性,来通知将会使用模板控件类型的运行时;[TemplateContainer(typeof(TemplatedListItem))]
5、创建容器类实例或子控件实例,使用InstantiateIn方法内联它们,并绑定数据到容器实例或子控件实例,最后把它们添加到服务器控件集 合中去;

动态模板:
1、定义一个类实现ITemplate接口;
2、在这个类中实现ITemplate唯一的方法InstantiateIn;

创建一个简单的模板化数据绑定控件步骤:
1、定义实现INamingContainer接口的控件;
2、定义Itemplate类型的属性;模板的逻辑容器(在 TemplateContainerAttribute 属性中指定)必须具有要将数据绑定到的属性。根据约 定,该属性名为DataItem
3、重写 DataBind 方法(继承自 Control)以提供数据绑定逻辑。此操作必须包括以下步骤:
     a:调用基类的 OnDataBinding 方法以调用对您的控件计算数据绑定表达式的处理程序(由该页附加)。
     b:清除 Controls 集合。
     c:清除子控件的 ViewState。
     d:使用数据源创建子控件。
     e:向 ASP.NET 页框架发出信号以跟踪控件的 ViewState。
4、重写 CreateChildControls 以在回发方案中重新创建子控件。这涉及清除 Controls 集合以及使用视图状态而不是数据源创建控件层次 结构。
5、定义一个具有空元素的数据源,并且在回发期间创建控件层次结构时使用该数据源而不是实际数据源。步骤 3 和步骤 4 分别使用该数据源和保存的视图状态创建控件层次结构。虚拟数据源使控件能够为这两个步骤的公共元素实现单个代码路径。(方法CreateControlHierarchy)

模板化控件

1.模板是页面语法中的一部分,可以包括带有静态HTML以及其它文字文本的服务器控件.
2.模板控件提供了重要的自定义能力,通常被称作无外观控件(lookless controls),因为它并没能生成预先确定的用户界面.
3.样式可以使我们定制生成UI的可视化外观,模板可以使我们自定义所生成的UI的内容.
4.页面解析器解析模板标签(<%# Container.DataItem%> )内的文本,并生成一个解析树来表示模板的内容,就像解析整个页面时一样.
5.解析器用解析树(由System.Web.UI.ControlBuilder对象组成)来创建ITemplate类型的一个实例.
6.该ITemplate实例可以在给定的容器控件中创建表示模板内容的控件层次.
ITemplate接口的定义:
public interface ITemplate
{
    void InstantiateIn(Control container);
}.

InstantiateIn方法的描述:
A.InstantiatenIn方法实例化该模板的元素,作为该模板容器的子控件.
B.当由类实现时,定义子控件和模板所属的Control对象.然后在内联模板中定义这些子控件.
C.Iteratively populates a provided control with a subhierarchy of child controls represented by the template.

7.解析器把该ITemplate实例赋值给控件相应的ITmplate属性.当构造控件层次时,控件可以多次调用模板的InstantiateIn方法,每次调用时模板创建由模板的内容表示的控件树的一个副本.
8.模板通常在数据绑定控件的环境中用到.

开发模板化控件的方法:
1.实现 System.Web.UI.INamingContainer 接口.(它可以在控件下创建新的命名范围,这样子控件就在名称树中有了唯一的标识符).
2.将 ParseChildrenAttribute 应用到控件,并传递 true 作为参数.在ASP.NET页上声明性地使用控件时,这样可以指示页分析器如何分析模板属性标记.(也就是说,应用这个元数据属性,可以使页分析器正确的分析模板的属性标记.
[注意:如果控件从WebControl派生,则不用了,因为WebControl已经用该属性作为标记.
3.定义一个或多 System.Web.UI.ITemplate类型的属性.这个属性必须有 System.Web.UI.TemplateContainerAttribute 类型的无数据属性,它指出这个 ITemplate 类型的属性将被哪种 INamingContainer 控件所拥有.(也就是说,用TemplateContainerAttribute元数据属性来标识出控件的模板的容器)
4.为你正在创建的模板化控件创建一个独立的容器控件.(创建这个东西的原因我现在不太清楚,请参见以后关于 模板化数据绑定控件的内容.
5.重写CreateChildControls方法,在模板中创建子控件.
    A.实例化模板容器.
    B.调用模板属性的 InstantiateIn方法并将该容器作为参数传递给它.
    C.将模板容器的示例添加到你的模板化控件的Controls 集合.
示例:
private Control myTemplateContainer;
protected override void CreateChildControls()
{
    if(FirstTemplate != null)
    {
        myTemplateContainer = new FirstTemplateContainer(this);
        FirstTemplate.InstantiateIn(myTemplateContainer);
        Controls.Add(myTemplateContainer);
    }
    else
    {
        Controls.Add(new LiteralControl(Text + " " + DateTime));
    }
}

6.重写从 Control继承的 OnDataBinding 方法:
protected override void OnDataBinding(EventArgs e)
{
    EnsureChildControls();
    base.OnDataBinding(e);
}

EnsureChildControls方法保证在数据绑定之前创建模板中的子控件.
调用基类的 OnDataBinding 方法发确保调用已注册的事件处理程序.

7.对控件中的每一个模板属性执行以上步骤.

发表于 @ 2006年11月08日 23:42:00 | 评论( loading... ) | 编辑| 举报| 收藏

旧一篇:在.net中开发复合控件 | 新一篇:CS2中的CSContext

  • 发表评论
  • 评论内容:
  •  
Copyright © ekun008
Powered by CSDN Blog