动态创建 ASP.NET Web 服务器控件模板

如何:动态创建 ASP.NET Web 服务器控件模板 

使用诸如 DataList 控件这样的模板化控件时,直到运行时,您可能才会知道需要什么模板或模板中应包含哪些文本或控件。在这种情况下,您可以在代码中动态创建模板。

Note注意

还可以将模板创建为用户控件,并将其动态绑定到页上的控件。有关详细信息,请参见如何:创建模板化的 ASP.NET 用户控件

在代码中,您可以为所有使用模板的控件(DataListRepeaterGridViewFormViewDetailsView 控件)创建模板。对于 GridView 控件,您要使用的是定义列的模板,而不是其他控件的行布局模板。

Note注意

在为 GridView 控件创建模板列时,存在一些不同之处。有关详细信息,请参见在 GridView Web 服务器控件中创建自定义列

<script type="text/Javascript"> var ExpCollDivStr=ExpCollDivStr; ExpCollDivStr = ExpCollDivStr + "ctl00_LibFrame_ctl09f290528,"; var ExpCollImgStr = ExpCollImgStr; ExpCollImgStr = ExpCollImgStr + "ctl00_LibFrame_ctl09img,"; </script> 创建模板类

要创建动态模板,请创建以后需要时可实例化的模板类。

创建模板类

  1. 创建实现 System.Web.UI.ITemplate 接口的新类。

  2. 您也可以将值传递到类的构造函数,类可以使用该值来确定要创建的模板类型(ItemTemplateAlternatingItemTemplate 等)。

    Note注意

    将模板类型传递到构造函数的类型安全方法是向构造函数添加类型为 ListItemType 的参数。ListItemType 枚举为 RepeaterDataList 和其他控件定义可能的模板类型。

  3. 在类中,实现 InstantiateIn 方法,该方法是 ITemplate 接口的成员。

    此方法提供将文本实例和控件实例插入指定容器的方法。

  4. InstantiateIn 方法中,为模板项创建控件,设置其属性,然后将它们添加到父级的 Controls 集合。

    您可以通过传递到 InstantiateIn 方法的引用访问父控件。

    Note注意

    不能直接向 Controls 集合添加静态文本,但可以创建类似 Literal 控件或 LiteralControl 控件的控件,设置它们的 Text 属性,然后向父集合添加这些控件。

    下面的代码示例阐释完整的模板类,该类显示某些静态文本(“Item number:”)和计数器。计数器是名为 itemcount 的静态值(在 Visual Basic 中为共享值),在每次创建新项时都会递增。该类定义一个接受 ListItemType 枚举值以指示所创建模板类型的显式构造函数。根据所创建的模板类型,代码创建不同类型的控件并将其添加到父控件的 Controls 集合。最终结果是一个 HTML 表,其中的交替项模板具有不同的背景色。

    Visual Basic
    Public Class MyTemplate
    Implements ITemplate
    Shared itemcount As Integer = 0
    Dim TemplateType As ListItemType

    Sub New(ByVal type As ListItemType)
    TemplateType = type
    End Sub

    Sub InstantiateIn(ByVal container As Control) _
    Implements ITemplate.InstantiateIn

    Dim lc As New Literal()

    Select Case TemplateType
    Case ListItemType.Header
    lc.Text = "<TABLE border=1><TR><TH>Items</TH></TR>"
    Case ListItemType.Item
    lc.Text = "<TR><TD>Item number: " & itemcount.ToString _
    & "</TD></TR>"
    Case ListItemType.AlternatingItem
    lc.Text = "<TR><TD bgcolor=lightblue>Item number: " _
    & itemcount.ToString & "</TD></TR>"
    Case ListItemType.Footer
    lc.Text = "</TABLE>"
    End Select

    container.Controls.Add(lc)
    itemcount += 1

    End Sub
    End Class
    C#
    public class MyTemplate : ITemplate
    {
    static int itemcount = 0;
    ListItemType templateType;

    public MyTemplate(ListItemType type)
    {
    templateType = type;
    }

    public void InstantiateIn(System.Web.UI.Control container)
    {
    Literal lc = new Literal();
    switch (templateType)
    {
    case ListItemType.Header:
    lc.Text = "<TABLE border=1><TR><TH>Items</TH></TR>";
    break;
    case ListItemType.Item:
    lc.Text = "<TR><TD>Item number: " + itemcount.ToString() +
    "</TD></TR>";
    break;
    case ListItemType.AlternatingItem:
    lc.Text = "<TR><TD bgcolor=lightblue>Item number: " +
    itemcount.ToString() + "</TD></TR>";
    break;
    case ListItemType.Footer:
    lc.Text = "</TABLE>";
    break;
    }
    container.Controls.Add(lc);
    itemcount += 1;
    }
    }

<script type="text/Javascript"> var ExpCollDivStr=ExpCollDivStr; ExpCollDivStr = ExpCollDivStr + "ctl00_LibFrame_ctl1744bf118,"; var ExpCollImgStr = ExpCollImgStr; ExpCollImgStr = ExpCollImgStr + "ctl00_LibFrame_ctl17img,"; </script> 使用动态模板

有了可用的动态模板,就可以在代码中将其实例化了。

创建动态模板

  1. 创建动态模板的实例,如果合适的话,将一个项类型值传递给它。

  2. 将该实例分配给模板化控件的模板属性之一,如 ItemTemplateAlternatingItemTemplateHeaderTemplate 属性。

    下面的代码示例演示如何与 Repeater 控件一起使用动态模板。在此示例中,在加载页时,而且是在控件绑定到数据源之前,将模板实例化。

    Visual Basic
    Private Sub Page_Load(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles MyBase.Load

    Dim conn As SqlConnection = _
    New SqlConnection(ConfigurationManager.ConnectionStrings("Northwind").ConnectionString)
    Dim SqlDataAdapter1 As SqlDataAdapter
    Dim DsCategories1 As DataSet

    SqlDataAdapter1 = New SqlDataAdapter("SELECT CategoryID, CategoryName FROM Categories", conn)
    DsCategories1 = new Dataset()

    Repeater1.HeaderTemplate = New MyTemplate(ListItemType.Header)
    Repeater1.ItemTemplate = New MyTemplate(ListItemType.Item)
    Repeater1.AlternatingItemTemplate = _
    New MyTemplate(ListItemType.AlternatingItem)
    Repeater1.FooterTemplate = New MyTemplate(ListItemType.Footer)
    SqlDataAdapter1.Fill(DsCategories1, "Categories")
    Repeater1.DataSource = DsCategories1.Tables("Categories")
    Repeater1.DataBind()

    End Sub
    C#
    private void Page_Load(object sender, System.EventArgs e)
    {
    SqlConnection conn =
    new SqlConnection(ConfigurationManager.ConnectionStrings["Northwind"].ConnectionString);

    SqlDataAdapter sqlDataAdapter1;
    DataSet dsCategories1;

    sqlDataAdapter1 = new SqlDataAdapter("SELECT CategoryID, CategoryName FROM Categories", conn);
    dsCategories1 = new DataSet();

    Repeater1.HeaderTemplate = new MyTemplate(ListItemType.Header);
    Repeater1.ItemTemplate = new MyTemplate(ListItemType.Item);
    Repeater1.AlternatingItemTemplate =
    new MyTemplate(ListItemType.AlternatingItem);
    Repeater1.FooterTemplate = new MyTemplate(ListItemType.Footer);
    sqlDataAdapter1.Fill(dsCategories1, "Categories");
    Repeater1.DataSource = dsCategories1.Tables["Categories"];
    Repeater1.DataBind();
    }
<script type="text/Javascript"> var ExpCollDivStr=ExpCollDivStr; ExpCollDivStr = ExpCollDivStr + "ctl00_LibFrame_ctl206dfee2c,"; var ExpCollImgStr = ExpCollImgStr; ExpCollImgStr = ExpCollImgStr + "ctl00_LibFrame_ctl20img,"; </script> 向模板添加数据绑定

根据创建类的方法,可以用多种方法访问模板类中的数据。一种方法是页框架自行实现数据绑定 - 当您向模板添加控件时,也会为这些控件的 DataBinding 事件添加处理程序。在创建了模板项及其所有控件后,会引发此事件,这样您就有机会获取数据并在控件中使用数据。

Note注意

在模板中创建控件时,不能像在设计时定义模板那样将数据绑定表达式作为字符串嵌入,因为数据绑定表达式会在创建模板之前转换为代码。

DataBinding 事件的处理程序中,您有机会操作控件的内容。通常(并非一定),您从某处获取数据并将其分配给控件的 Text 属性。

Note注意

有关 ASP.NET 网页中的数据绑定的背景信息,请参见通过 ASP.NET 访问数据

要将数据绑定添加到动态模板,必须执行如下操作:

  • 将数据绑定事件处理程序添加到您在模板中创建的控件。

  • 创建您要被绑定的处理程序。在该处理程序中,获取您要被绑定的数据并将其分配给要被绑定控件的相应属性。

添加数据绑定事件处理程序

  • 在动态模板中创建控件后,添加对控件的 DataBinding 事件的事件处理程序的引用。(接下来您将创建事件处理程序)。

    下面的代码示例演示了模板类的一部分,该部分阐释了如何将新创建的控件绑定到名为 TemplateControl_DataBinding 的方法:

    Visual Basic
    Dim lc As New Literal()

    Select Case TemplateType
    Case ListItemType.Item
    lc.Text = "<TR><TD>"
    AddHandler lc.DataBinding, AddressOf TemplateControl_DataBinding
    End Select
    C#
    case ListItemType.Item:

    lc.Text = "<TR><TD>";
    lc.DataBinding += new EventHandler(TemplateControl_DataBinding);
    break;

    在上例中,您添加到文本控件的 Text 属性的文本不同于前一示例。该示例只包含了项模板的表行和单元格的开头。您将在数据绑定事件处理程序中填写单元格和行。

下一步是创建事件处理程序,在控件处于数据绑定状态时将调用该事件处理程序。

为 DataBinding 事件创建处理程序

  1. 创建属于模板类的方法,它还是该类的其他方法(如 InstantiateIn)的对等方法。处理程序的名称必须与早期绑定事件时使用的名称相匹配。该方法应该具有以下签名:

    Visual Basic
    Private Sub TemplateControl_DataBinding(ByVal sender As Object, _
    ByVal e As System.EventArgs)
    C#
    private void TemplateControl_DataBinding(object sender,
    System.EventArgs e)
  2. 通过执行以下操作获取对包含数据的 DataItem 对象的引用:

    1. 获取对模板项的引用。创建变量来保存该引用,然后将从控件的 NamingContainer 属性获取的值分配给它。

    2. 使用该引用来获取命名容器的(模板项的)DataItem 属性。

    3. DataItem 对象提取单个数据元素(例如数据列),并使用它来设置您要绑定的控件的属性。

      下面的代码示例阐释在动态模板内执行数据绑定的一种方式。它演示了在 Repeater 控件的模板中创建的 Literal 控件的完整数据绑定事件处理程序。

      Visual Basic
      Private Sub TemplateControl_DataBinding(ByVal sender As Object, _
      ByVal e As System.EventArgs)

      Dim lc As Literal
      lc = CType(sender, Literal)

      Dim container As RepeaterItem

      container = CType(lc.NamingContainer, RepeaterItem)
      lc.Text &= DataBinder.Eval(container.DataItem, "CategoryName")
      lc.Text &= "</TD></TR>"
      End Sub
      C#
      private void TemplateControl_DataBinding(object sender,
      System.EventArgs e)
      {

      Literal lc;

      lc = (Literal)sender;
      RepeaterItem container = (RepeaterItem)lc.NamingContainer;
      lc.Text += DataBinder.Eval(container.DataItem, "CategoryName");
      lc.Text += "</TD></TR>";
      }
      Note注意

      如果在您的模板中具有多种类型的控件,您需要为每一种控件类型创建一个不同的数据绑定事件处理程序。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值