65.9K
CodeProject 正在变化。 阅读更多。
Home

ASP.NET 设计时数据绑定自定义控件

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.86/5 (3投票s)

2007年8月21日

1分钟阅读

viewsIcon

28222

当自定义控件位于数据绑定组合控件内部时,ASP.NET 设计时数据绑定自定义控件。

引言

本文档描述了如何在数据绑定组合控件的模板中使用自定义 Web 控件时,为其提供设计时数据绑定功能。例如,如果您将自定义 Web 控件添加到 asp:RepeaterItemTemplate 中。

背景

当自定义 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。
© . All rights reserved.