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

由于各种原因,直到运行时,您可能才会知道需要什么模板或模板中应包含哪些文本或控件。在这种情况下,您需要能够动态创建该模板(在代码中)。

注意   您还可以将模板创建为 Web 窗体用户控件,并将其动态绑定到页上的控件。有关详细信息,请参见 创建模板用户控件

在代码中,您可以为所有使用模板的控件(DataListRepeaterDataGrid 控件)创建模板。对于 DataGrid 控件,您要使用的是定义列的模板,而不是其他两个控件的与行类似的模板。

注意   为 DataGrid 控件创建模板列时有一些差异。有关详细信息,请参见 在 DataGrid 控件中以编程方式创建模板

创建模板类

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

注意   有关在 Visual Basic .NET 中创建类的背景,请参见 了解类。有关 Visual C# .NET 的类似信息,请参见 class

创建模板类

  1. 创建新类,它可以实现 System.Web.UI 命名空间的 ITemplate 接口。
  2. 您也可以将值传递到类的构造函数。类可以使用该值来确定要创建的模板类型(ItemTemplateAlternatingItemTemplate 等)。
    提示   将模板类型传递到构造函数的类型安全方式是:给 ListItemType 类型的构造函数添加参数。 ListItemType 枚举为 RepeaterDataList DataGrid 控件定义可能的模板类型。
  3. 在该类中,实现 InstantiateIn 方法(ITemplate 接口的唯一成员)。此方法提供将文本实例和控件实例插入指定容器的方法。
  4. InstantiateIn 方法中,为模板项创建控件,设置其属性,然后将它们添加到父级的 Controls 集合。您可以通过传递到 InstantiateIn 方法的引用访问父控件。
    注意   不能直接将静态文本添加到 Controls 集合,但可以创建类似 Literal 控件或 LiteralControl 控件的控件,设置它们的 Text 属性,然后将这些控件添加到父集合。

    下面的示例说明完整的模板类,该类显示某些静态文本(“Item number:”)和计数器。计数器是类的名为 itemcount 的共享值或静态值(根据您所用的语言),在每次创建新项时都会递增。

    该类定义一个接受 ListItemType 枚举值以指示所创建模板类型的显式构造函数。根据所创建的模板类型,代码创建不同类型的控件并将其添加到父控件的 Controls 集合。最终结果是一个 HTML 表,其中的交替项模板具有不同的背景色。

     

' Visual Basic
Private 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;
   }
}

  1. 使用动态模板

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

注意   若要将动态模板作为 DataGrid 控件中的列使用,请参见 在 DataGrid 控件中以编程方式创建模板

创建动态模板

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

将该实例分配给 Repeater 控件或 DataList 控件的模板属性之一:ItemTemplate、AlternatingItemTemplate、HeaderTemplate 等。

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

 

' Visual Basic
Private Sub Page_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
   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)
   Repeater1.DataBind()
End Sub

// C#
private void Page_Load(object sender, System.EventArgs e)
{
   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);
   Repeater1.DataBind();
}

  1. 向模板添加数据绑定

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

注意   在模板中创建控件时,您不能像在设计时定义模板那样,将数据绑定表达式作为字符串嵌入,因为数据绑定表达式会在页处理阶段(发生在创建您的模板之前)转换为代码。

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

注意   有关 Web 窗体页中数据绑定的背景信息,请参见 Web 窗体数据绑定

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

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

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

  • 在动态模板中创建控件后,使用标准命令将控件的 DataBinding 事件绑定到稍后您将创建的方法。
    注意   有关如何动态添加事件处理程序的详细信息,请参见 AddHandler 和 RemoveHandler(对于 Visual Basic)和 事件教程(对于 Visual C#)。

    下面的示例显示了模板类中的代码,该代码阐释了如何将新创建的控件绑定到名为 TemplateControl_DataBinding 的方法。

     

' Visual Basic
Dim lc As New Literal()
   Case ListItemType.Item
   lc.Text = "<TR><TD>"
   AddHandler lc.DataBinding, AddressOf TemplateControl_DataBinding

// C#
Literal lc = new Literal();
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)

  1. 获取对包含当前模板项的数据的 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>";
    }

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

转载于:https://www.cnblogs.com/mcsm/articles/1832640.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值