来自asp.net快速入门教程 自定义控件(1)

来自asp.net快速入门教程的自定义控件

目录
1。控件的生成逻辑
2。开发复合控件
3。在复合控件中处理事件
4。从复合控件中引发自定义事件
5。维护状态
6。开发处理回发数据的自定义(非复合)控件
7。为自定义回发生成客户端 JavaScrip
'--------------------------------------------------------------------------------------------

1。控件生成逻辑
  
  每个控件都具有从 System.Web.UI.Control 继承的 Controls 属性。
  这是表示控件的子控件(如果有)的集合属性。
  
  如果控件未用 ParseChildrenAttribute 标记
  或是标记为 ParseChildrenAttribute(ChildrenAsProperties = false)
  则当控件在页上以声明方式使用时,ASP.NET 页框架将应用以下分析逻辑。
  
  如果分析器在控件的标记内遇到嵌套控件,它将创建嵌套控件的实例并将它们添加到控件的 Controls 属性。
  标记之间的文本添加为 LiteralControl。任何其他嵌套元素都生成分析器错误。

    EXP
 
'*******************************************************************************************  
    SimpleInnerContent.aspx

    <%@ Register TagPrefix="SimpleControlSamples" Namespace="SimpleControlSamples"

Assembly="SimpleControlSamplesVB" %>
<html>
   <body>
      <form method="POST" runat="server">
          <SimpleControlSamples:SimpleInnerContentVB id="MyControl" runat=server>
             我的消息在控件标记内!!!!
          </SimpleControlSamples:SimpleInnerContentVB>
      </form>
   </body>
</html>
'*******************************************************************************************
   SimpleInnercontent.vb

Option Strict Off
Imports System
Imports System.Web
Imports System.Web.UI
Namespace SimpleControlSamples
    Public Class SimpleInnerContentVB : Inherits Control
       Protected Overrides Sub Render(Output As HtmlTextWriter)
           If HasControls() And TypeOf Controls(0) Is LiteralControl
              Dim Ctrl As LiteralControl = Controls(0)
              Output.Write("<H2>您的消息:" & Ctrl.Text & "</H2>")
           End If
       End Sub
    End Class
End Namespace
'********************************************************************************************

注意:如果自定义控件是从 WebControl 派生的,它将不具有示例中描述的分析逻辑
      因为 WebControl 是用 ParseChildrenAttribute(ChildrenAsProperties = true) 标记的
      这导致不同的分析逻辑。有关 ParseChildrenAttribute 的更多信息,请参阅 SDK 文档。


'--------------------------------------------------------------------------------------------

2。开发复合控件:
 
可以通过使用类撰写组合现有控件来创作新控件。
复合控件等效于使用 ASP.NET 页语法创作的用户控件。
用户控件和复合控件之间的主要差异是用户控件保持为 .ascx 文本文件
而复合控件则经过编译并保持在程序集中。

开发复合控件的主要步骤是:

重写从 Control 继承的受保护的 CreateChildControls 方法:
 以创建子控件的实例并将它们添加到控件集合。
如果复合控件的新实例将在页上重复创建:
 请实现 System.Web.UI.INamingContainer 接口。
 这是不具有方法的标记接口。
 当用控件实现时,ASP.NET 页框架将在此控件下创建新的命名范围。
 这确保了子控件在控件层次结构树中具有唯一的 ID。
 因为子控件会提供呈现逻辑,所以不必重写 Render 方法。可以公开合成子控件属性的属性。

EXP

'****************************************************************************************
'Composition1.aspx

<%@ Register TagPrefix="CompositionSampleControls" Namespace="CompositionSampleControls"

Assembly="CompositionSampleControlsVB" %>
<html>
   <script language="VB" runat=server>
      Private Sub AddBtn_Click(Sender As Object, E As EventArgs)
          MyControl.Value = MyControl.Value + 1
      End Sub
      Private Sub SubtractBtn_Click(Sender As Object, E As EventArgs)
          MyControl.Value = MyControl.Value - 1
      End Sub
   </script>
   <body>
      <form method="POST" action="Composition1.aspx" runat=server>
          <CompositionSampleControls:Composition1VB id="MyControl" runat=server/>
          <br>
          <asp:button text="加" OnClick="AddBtn_Click" runat=server/> |
          <asp:button text="减" OnClick="SubtractBtn_Click" runat=server/>
      </form>
   </body>
</html>
'****************************************************************************************
'Composition1.aspx

Option Strict Off
Imports System
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Namespace CompositionSampleControls
    Public Class Composition1VB : Inherits Control : Implements INamingContainer
        Public Property Value As Integer
           Get
               Dim Ctrl As TextBox = Controls(1)
               Me.EnsureChildControls()
               Return Int32.Parse(Ctrl.Text)
           End Get
           Set
               Dim Ctrl As TextBox = Controls(1)
               Me.EnsureChildControls()
               Ctrl.Text = Value.ToString()
           End Set
        End Property
        Protected Overrides Sub CreateChildControls()
            Me.Controls.Add(New LiteralControl("<h3>" & "值:"))
            Dim Box As New TextBox
            Box.Text = "0"
            Me.Controls.Add(box)
            Me.Controls.Add(New LiteralControl("</h3>"))
        End Sub
    End Class
End Namespace
'****************************************************************************************

'--------------------------------------------------------------------------------------------

3。在复合控件中处理事件
  下面的示例显示复合控件 Composition2,
  该控件将两个按钮控件(名为 Add 和 Subtract)添加到上一示例中的复合控件,
  并为按钮的 Click 事件提供事件处理方法。
  这些方法增加和减少 Composition2 的 Value 属性。
  Composition2 的 CreateChildControls 方法创建引用这些方法的事件处理程序(委托)的实例,
  并将委托附加到 Button 实例的 Click 事件。
  最后得到一个进行自己的事件处理的控件——单击 Add 按钮时,文本框中的值增加;单击 Subtract 按钮时,值减少。

EXP
'****************************************************************************************
'Composition2.aspx
<%@ Register TagPrefix="CompositionSampleControls" Namespace="CompositionSampleControls"

Assembly="CompositionSampleControlsVB" %>
<html>
   <body>
      <form method="POST" action="Composition2.aspx" runat=server>
          <CompositionSampleControls:Composition2VB id="MyControl" runat=server/>
      </form>
   </body>
</html>
'****************************************************************************************
'Composition2.vb
Option Strict Off
Imports System
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Namespace CompositionSampleControls
    Public Class Composition2VB : Inherits Control : Implements INamingContainer
        Public Property Value As Integer
           Get
               Dim Ctrl As TextBox = Controls(1)
               Me.EnsureChildControls()
               Return Int32.Parse(Ctrl.Text)
           End Get
           Set
               Dim Ctrl As TextBox = Controls(1)
               Me.EnsureChildControls()
               Ctrl.Text = Value.ToString()
           End Set
        End Property
        Protected Overrides Sub CreateChildControls()
           ' 添加文本控件
           Me.Controls.Add(New LiteralControl("<h3>" & "值:"))
           ' 添加文本框
           Dim Box As New TextBox
           Box.Text = "0"
           Me.Controls.Add(Box)
           ' 添加文本控件
           Me.Controls.Add(New LiteralControl("</h3>"))
           ' 添加“加”按钮
           Dim AddButton As New Button
           AddButton.Text = "加"
           AddHandler AddButton.Click, AddressOf AddBtn_Click
           Me.Controls.Add(AddButton)
           ' 添加文本控件
           Me.Controls.Add(New LiteralControl(" | "))
           ' 添加“减”按钮
           Dim SubtractButton As New Button
           SubtractButton.Text = "减"
           AddHandler SubtractButton.Click, AddressOf SubtractBtn_Click
           Me.Controls.Add(SubtractButton)
        End Sub
        Private Sub AddBtn_Click(Sender As Object, E As EventArgs)
           Me.Value = Me.Value + 1
        End Sub
        Private Sub SubtractBtn_Click(Sender As Object, E As EventArgs)
           Me.Value = Me.Value - 1
        End Sub
    End Class
End Namespace


'****************************************************************************************

'--------------------------------------------------------------------------------------------
4。从复合控件中引发自定义事件

EXP
'****************************************************************************************
'Composition3.aspx
<%@ Register TagPrefix="CompositionSampleControls" Namespace="CompositionSampleControls"

Assembly="CompositionSampleControlsVB" %>
<html>
   <script language="VB" runat=server>
      Private Sub Composition2_Change(Sender As Object, E As EventArgs)
         If MyControl.Value < 0
            MyControl.Value = 0
         End If
      End Sub
   </script>
   <body>
      <form method="POST" action="Composition3.aspx" runat=server>
          <CompositionSampleControls:Composition3VB id="MyControl" OnChange="Composition2_Change"

runat=server/>
      </form>
   </body>
</html>
'****************************************************************************************
'Composition3.vb
Option Strict Off
Imports System
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Namespace CompositionSampleControls
    Public Class Composition3VB : Inherits Control : Implements INamingContainer
        Public Event Change(Sender as Object, E as EventArgs)
        Public Property Value As Integer
           Get
               Dim Ctrl As TextBox = Controls(1)
               Me.EnsureChildControls()
               Return Int32.Parse(Ctrl.Text)
           End Get
           Set
               Dim Ctrl As TextBox = Controls(1)
               Me.EnsureChildControls()
               Ctrl.Text = Value.ToString()
           End Set
        End Property
        Protected Sub OnChange(E As EventArgs)
            RaiseEvent Change(Me, E)
        End Sub
        Protected Overrides Sub CreateChildControls()
           ' 添加文本控件
           Me.Controls.Add(New LiteralControl("<h3>" & "值:"))
           ' 添加文本框
           Dim Box As New TextBox
           Box.Text = "0"
           AddHandler Box.TextChanged, AddressOf TextBox_Change
           Me.Controls.Add(Box)
           ' 添加文本控件
           Me.Controls.Add(New LiteralControl("</h3>"))
           ' 添加“加”按钮
           Dim AddButton As New Button
           AddButton.Text = "加"
           AddHandler AddButton.Click, AddressOf AddBtn_Click
           Me.Controls.Add(AddButton)
           ' 添加文本控件
           Me.Controls.Add(New LiteralControl(" | "))
           ' 添加“减”按钮
           Dim SubtractButton As New Button
           SubtractButton.Text = "减"
           AddHandler SubtractButton.Click, AddressOf Me.SubtractBtn_Click
           Me.Controls.Add(SubtractButton)
        End Sub
        Private Sub TextBox_Change(Sender As Object, E As EventArgs)
           OnChange(EventArgs.Empty)
        End Sub
        Private Sub AddBtn_Click(Sender As Object, E As EventArgs)
           Me.Value = Me.Value + 1
           OnChange(EventArgs.Empty)
        End Sub
        Private Sub SubtractBtn_Click(Sender As Object, E As EventArgs)
           Me.Value = Me.Value - 1
           OnChange(EventArgs.Empty)
        End Sub
    End Class
End Namespace
'****************************************************************************************

'--------------------------------------------------------------------------------------------

5。维护状态
 每个 Web 窗体控件都有一个 State 属性(从 Control 继承),
 该属性使 Web 窗体控件能够参与 State 管理。
 State 的类型为 Sytem.Web.UI.StateBag,等效于哈希表的数据结构。
 控件可以将数据作为键/值对保存在 State 中。
 State 通过 ASP.NET 页框架保持为字符串变量,并以隐藏变量的形式与客户端之间往返。
 回发时,页框架分析来自隐藏变量的输入字符串,
 并在页的控件层次结构中填充每个控件的 State 属性。
 通过使用 State 属性,控件可以还原其状态(将属性和字段设置为它们回发前的值)。

EXP
'****************************************************************************************
'Label.vb
Imports System
Imports System.Web
Imports System.Web.UI
Namespace ViewStateControlSamples
    Public Class LabelVB : Inherits Control
       Public Property [Text] As String
          Get
              Return CStr(ViewState("Text"))
          End Get
          Set
              ViewState("Text") = Value
          End Set
       End Property
       Public Property FontSize As Integer
          Get
              Return CInt(ViewState("FontSize"))
          End Get
          Set
              ViewState("FontSize") = Value
          End Set
       End Property
       Protected Overrides Sub Render(Output As HtmlTextWriter)
           Output.Write("<font size=" & Me.FontSize & ">" & Me.Text & "</font>")
       End Sub
    End Class
End Namespace
'****************************************************************************************

'--------------------------------------------------------------------------------------------

6。开发处理回发数据的自定义(非复合)控件

 下面的示例说明一个做更有意义的事情的自定义控件——它呈现输入框,并读入用户输入的数据。
 检查回发(输入)数据的控件必须实现 System.Web.UI.IPostBackDataHandler 接口。
 这将向 ASP.NET 页框架发出信号,指出控件应参与回发数据处理。
 页框架将输入数据作为键/值对传递给此接口的 LoadPostData 方法。
 在此方法的实现中,控件可以像下面这样检查输入数据并更新其属性。

EXP
'****************************************************************************************
'NonComposition1.vb
Imports System
Imports System.Web
Imports System.Web.UI
Imports System.Collections
Imports System.Collections.Specialized
Imports System.Web.UI.WebControls
Namespace NonCompositionSampleControls
    Public Class NonComposition1VB : Inherits Control : Implements IPostBackDataHandler
        Private _value As Integer = 0
        Public Property Value As Integer
           Get
               Return _value
           End Get
           Set
               _value = Value
           End Set
        End Property
        Public Function LoadPostData(PostDataKey As String, Values As NameValueCollection) As Boolean

Implements IPostBackDataHandler.LoadPostData
           _value = Int32.Parse(Values(Me.UniqueID))
           Return false
        End Function
        Public Sub RaisePostDataChangedEvent() Implements IPostBackDataHandler.RaisePostDataChangedEvent
           ' IPostBackDataHandler 协定的一部分。如果曾经从 LoadPostData 方法返回真
           ' (表示需要引发更改通知),则被调用。由于
           ' 始终返回假,则此方法只是一个空操作。
        End Sub
        Protected Overrides Sub Render(Output As HtmlTextWriter)
           Output.Write("<h3>值:<input name=" & Me.UniqueID & " type=text value=" & Me.Value & "> </h3>")
        End Sub
    End Class
End Namespace
'****************************************************************************************

'--------------------------------------------------------------------------------------------

7。为自定义回发生成客户端 JavaScrip

 如果控件要捕获回发事件(来自客户端的窗体提交),它必须实现 System.Web.UI.IPostBackEventHandler 接口。
 此接口向 ASP.NET 页框架发出信号,指出控件希望收到回发事件通知。
 RaisePostBackEvent 方法允许控件处理该事件和引发其他事件。
 另外,ASP.NET 页框架具有自定义事件结构,该结构允许控件生成启动自定义回发的客户端 JavaScript。
 回发通常仅由几个元素启动,如 Submit(提交)按钮或 Image(图像)按钮。
 不过,通过发出客户端 JavaScript,控件也可以从其他 HTML 元素启动回发。

 下面的示例定义一个在上一示例 NonComposition1 之上生成的自定义控件 NonComposition2。
 除了 NonComposition1 提供的接口,它还呈现两个 HtmlButtons,它们生成在单击时导致回发的客户端 JavaScript。
 这些按钮的名称属性是 Add 和 Subtract。
 名称属性以字符串参数的形式,通过页框架传递到 RaisePostBackEvent。
 NonComposition2 实现 RaisePostBackEvent

EXP
'****************************************************************************************
'NonComposition2.vb
Imports System
Imports System.Web
Imports System.Web.UI
Imports System.Collections
Imports System.Collections.Specialized
Imports System.Web.UI.WebControls
Namespace NonCompositionSampleControls
    Public Class NonComposition2VB : Inherits Control : Implements IPostBackDataHandler : Implements

IPostBackEventHandler
        Private _value As Integer = 0
        public Property Value As Integer
           Get
               Return _value
           End Get
           Set
               _value = Value
           End Set
        End Property
        Public Function LoadPostData(PostDataKey As String, Values As NameValueCollection) As Boolean

Implements IPostBackDataHandler.LoadPostData
           _value = Int32.Parse(values(Me.UniqueID))
           Return false
        End Function
        Public Sub RaisePostDataChangedEvent() Implements IPostBackDataHandler.RaisePostDataChangedEvent
           ' IPostBackDataHandler 协定的一部分。如果曾经从 LoadPostData 方法返回真
           ' (表示需要引发更改通知),则被调用。由于
           ' 始终返回假,则此方法只是一个空操作。
        End Sub
        Public Sub RaisePostBackEvent(EventArgument As String) Implements

IPostBackEventHandler.RaisePostBackEvent
           If (eventArgument = "加")
              Me.Value = Me.Value + 1
           Else
              Me.Value = Me.Value - 1
           End If
        End Sub
        Protected Overrides Sub OnPreRender(E As EventArgs)
           'Page.RegisterPostBackScript()
        End Sub
        Protected Overrides Sub Render(Output As HtmlTextWriter)
           Output.Write("<h3>值:<input name=" & Me.UniqueID & " type=text value=" & Me.Value & "> </h3>")
           Output.Write("<input type=button value=加 OnClick=""jscript:" & Page.GetPostBackEventReference(Me,

"加") & """> |")
           Output.Write("<input type=button value=减 OnClick=""jscript:" & Page.GetPostBackEventReference(Me,

"减") & """>")
        End Sub   
    End Class
End Namespace

'****************************************************************************************
'该页面被执行时,页面生成的代码如下:
<html>
   <body>
      <form name="_ctl0" method="POST" action="NonComposition2.aspx" id="_ctl0">
<input type="hidden" name="__VIEWSTATE" value="dDwtODg2MjkxNTg2Ozs+AAFx1AenyMXXe37jNzQ5JpnN+vA=" />
          <h3>值:<input name=MyControl type=text value=0> </h3><input type=button value=加

OnClick="jscript:__doPostBack('MyControl','加')"> |<input type=button value=减

OnClick="jscript:__doPostBack('MyControl','减')">
<input type="hidden" name="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" value="" />
<script language="javascript">
<!--
 function __doPostBack(eventTarget, eventArgument) {
  var theform = document._ctl0;
  theform.__EVENTTARGET.value = eventTarget;
  theform.__EVENTARGUMENT.value = eventArgument;
  theform.submit();
 }
// -->
</script>
</form>
   </body>
</html>
'****************************************************************************************
显示给客户端的用户界面与上一示例中的相同;
不过,整个 UI 由一个也处理回发事件的自定义控件来呈现。
页面开发人员只需将 NonComposition2 添加到页,不必提供任何事件处理逻辑。
'--------------------------------------------------------------------------------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值