Visual Basic 8 (2005)WebFormsVisual Studio 2005.NET 2.0中级开发Visual StudioWindows.NETVisual BasicASP.NET
ASP.NET 设计时数据绑定自定义控件






3.86/5 (3投票s)
2007年8月21日
1分钟阅读

28222
当自定义控件位于数据绑定组合控件内部时,ASP.NET 设计时数据绑定自定义控件。
引言
本文档描述了如何在数据绑定组合控件的模板中使用自定义 Web 控件时,为其提供设计时数据绑定功能。例如,如果您将自定义 Web 控件添加到 asp:Repeater 的 ItemTemplate 中。
背景
当自定义 Web 控件在数据绑定组合控件的模板中使用时,其设计器在设计时不会被使用,并且即使调用了 Databind 事件,数据绑定属性也不会被设置。为了正确地在设计时显示控件,必须使用 DataBindingHandler 来设置自定义 Web 控件的数据绑定属性。
使用代码
下面显示了一个通用 DataBinderHandler 的示例代码。此处理程序应能正确显示设计时任何 Bind("PropertName")、Eval("PropertyName") 或 DataBinder.Eval(Container,"PropertyName") 表达式。
为了告诉设计器使用 DataBinderHandler,您必须将 DataBindingHandler 属性添加到自定义 Web 控件。
<Designer(GetType(InvoiceControlDesigner)), _
DataBindingHandler(GetType(DEDataBindingHandler)), _
ToolboxData("<{0}:InvoiceControl runat="server"></{0}:InvoiceControl>")> _
Public Class InvoiceControl
    Inherits System.Web.UI.WebControls.CompositeControl
.....
End Class
Public Overrides Sub DataBindControl(ByVal designerHost As _
       System.ComponentModel.Design.IDesignerHost, _ 
       ByVal control As System.Web.UI.Control)
  Dim myIDataBindingAccesor As IDataBindingsAccessor = control
  If myIDataBindingAccesor.HasDataBindings Then
  For Each mydatabinding As DataBinding In _
           myIDataBindingAccesor.DataBindings
    Dim pinfo As System.Reflection.PropertyInfo
    pinfo = control.GetType.GetProperty(mydatabinding.PropertyName, _
            mydatabinding.PropertyType, System.Type.EmptyTypes)
    If pinfo IsNot Nothing Then
        Dim MyValue As Object = Nothing
        Select Case mydatabinding.PropertyType.FullName
          Case "System.String"
            MyValue = "ABC"
          Case "System.Date"
            MyValue = #1/1/1970#
          Case "System.Integer", "System.Long"
            MyValue = 123
          Case "System.Single", "System.Double"
            MyValue = 12.34
          Case Else
            MyValue = "DataBound"
        End Select
        Try
          If control.BindingContainer IsNot Nothing AndAlso _ 
            TypeOf control.BindingContainer Is IDataItemContainer Then
             If mydatabinding.Expression.ToLower.StartsWith("bind(""") Or _
              mydatabinding.Expression.ToLower.StartsWith("eval(""") Or _
              mydatabinding.Expression.ToLower.StartsWith("databinder.eval(container") Then
               Dim StartPosition As Integer = mydatabinding.Expression.IndexOf("(")
               Dim FormatPosition As Integer
               Dim ExPrefix As String = ""
               If Not mydatabinding.Expression.ToLower.StartsWith(_
                          "databinder.eval(container") Then
                 ExPrefix = "DataItem."
               Else
                 StartPosition = mydatabinding.Expression.IndexOf(",", StartPosition) + 2
               End If
               FormatPosition = mydatabinding.Expression.IndexOf(",", StartPosition)
               Dim mydatabindingex As String = ""
               If FormatPosition > 4 Then
                 mydatabindingex = mydatabinding.Expression.Substring(StartPosition, _
                                   FormatPosition - StartPosition + 1)
                 Dim FormatString As String
                 FormatString = mydatabinding.Expression.Substring(FormatPosition + 2, _
                                mydatabinding.Expression.Length - FormatPosition - 4)
                 MyValue = DataBinder.Eval(control.BindingContainer, _
                           ExPrefix & mydatabindingex, FormatString)
               Else
                 mydatabindingex = mydatabinding.Expression.Substring(StartPosition, _
                                   mydatabinding.Expression.Length - StartPosition - 2)
                 MyValue = DataBinder.Eval(control.BindingContainer, _
                           ExPrefix & mydatabindingex)
               End If
             End If
          End If
        Catch ex As Exception
          Debug.WriteLine("DataBinderHandler Failed " & ex.ToString)
        End Try
        If System.Type.Equals(MyValue.GetType, mydatabinding.PropertyType) Then
          pinfo.SetValue(control, MyValue, Nothing)
        End If
      End If
    Next
  End If
End Sub
End Class
ASP.NET 代码
<asp:Repeater ID="Repeater1" runat="server" 
  DataMember="InvoiceList" DataSourceID="DEDataSource1">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" 
  Text='<%# Bind("InvoiceID") %>'></asp:Label>
<DE:InvoiceControl ID="InvoiceControl1" runat="server" 
  Invoice='<%# Databinder.Eval(Container,"DataItem") %>' 
  LogoImagePath="http://www.digitalexample.com/images/delogo.gif" 
  InvoiceControlMode="ReadOnly" InvoiceControlStyle="Default" >
<InvoiceTableStyle CellPadding="3" 
  CellSpacing="0" Height="100%" Width="100%" />
</DE:InvoiceControl>
关注点
在弄清楚为什么我的自定义控件放置在 Repeater 内部后无法工作之前,我花了很多时间。调试显示数据绑定属性没有被设置,但数据绑定事件正在被调用。我还注意到在设计时,设计器没有调用 PreRender 事件。我不确定为什么 Microsoft 没有包含一个通用的 DataBindingHandler,当没有设置 DataBindingHandler 属性时使用。
历史
- 最初发布于 2007 年 8 月 21 日,作者:Andrew DeVries。
