俺也不知道怎么翻译好,意思就是说将一些常见的服务器控件如:TEXTBOX,RADIOBUTTON,DROPDOWNLIST,CHECKBOX等控件放入该服务器控件模版内,就能在提交的时候记录这些控件的信息,一般都是用户的搜索条件,如果用户从当前页转到其他页,再转回来时,那些控件上的信息依然保留,用这个控件比较方便,代码改动量非常小,如果想要实现更多的控件信息能保存你需要对该服务器控件做简单的扩展.以下是创建步骤和代码:
一.创建一个ASP .net server control project,重命名默认类比如叫SmartFilter,在SmartFilter中引入System.Design ,该引用使得你可以使用System.Web.UI.Design
二.拷贝以下代码到SmartFilter类,然后编译ASP .net server control project
代码:
- 'Imports System
- 'Imports System.Collections.Generic
- 'Imports System.ComponentModel
- 'Imports System.Text
- 'Imports System.Web
- 'Imports System.Web.UI
- 'Imports System.Web.UI.WebControls
- '<DefaultProperty("Text"), ToolboxData("<{0}:ServerControl1 runat=server></{0}:ServerControl1>")> _
- 'Public Class SmartFilter
- ' Inherits WebControl
- ' <Bindable(True), Category("Appearance"), DefaultValue(""), Localizable(True)> Property Text() As String
- ' Get
- ' Dim s As String = CStr(ViewState("Text"))
- ' If s Is Nothing Then
- ' Return "[" + Me.ID + "]"
- ' Else
- ' Return s
- ' End If
- ' End Get
- ' Set(ByVal Value As String)
- ' ViewState("Text") = Value
- ' End Set
- ' End Property
- ' Protected Overrides Sub RenderContents(ByVal output As HtmlTextWriter)
- ' output.Write(Text)
- ' End Sub
- 'End Class
- Option Strict On
- Imports System
- Imports System.ComponentModel
- Imports System.Drawing
- Imports System.Security.Permissions
- Imports System.Web
- Imports System.Web.UI
- Imports System.Web.UI.WebControls
- Imports System.Web.UI.Design
- <AspNetHostingPermission(SecurityAction.Demand, _
- Level:=AspNetHostingPermissionLevel.Minimal), _
- AspNetHostingPermission(SecurityAction.InheritanceDemand, _
- Level:=AspNetHostingPermissionLevel.Minimal), _
- Designer(GetType(SmartFilterDesigner)), _
- DefaultProperty("Title"), _
- ToolboxData( _
- "<{0}:SmartFilter runat=""server""> </{0}:SmartFilter>") _
- > _
- Public Class SmartFilter
- Inherits CompositeControl
- Private _template As ITemplate
- Private _owner As TemplateOwner
- < _
- Bindable(True), _
- Category("Data"), _
- DefaultValue(""), _
- Description("Caption") _
- > _
- Public Overridable Property Caption() As String
- Get
- Dim s As String = CStr(ViewState("Caption"))
- If s Is Nothing Then s = String.Empty
- Return s
- End Get
- Set(ByVal value As String)
- ViewState("Caption") = value
- End Set
- End Property
- < _
- Browsable(False), _
- DesignerSerializationVisibility( _
- DesignerSerializationVisibility.Hidden) _
- > _
- Public ReadOnly Property Owner() As TemplateOwner
- Get
- Return _owner
- End Get
- End Property
- < _
- Browsable(False), _
- PersistenceMode(PersistenceMode.InnerProperty), _
- DefaultValue(GetType(ITemplate), ""), _
- Description("Control template"), _
- TemplateContainer(GetType(SmartFilter)) _
- > _
- Public Overridable Property Template() As ITemplate
- Get
- Return _template
- End Get
- Set(ByVal value As ITemplate)
- _template = value
- End Set
- End Property
- < _
- Bindable(True), _
- Category("Data"), _
- DefaultValue(""), _
- Description("Title"), _
- Localizable(True) _
- > _
- Public Property Title() As String
- Get
- Dim s As String = CStr(ViewState("Title"))
- If s Is Nothing Then s = String.Empty
- Return s
- End Get
- Set(ByVal value As String)
- ViewState("Title") = value
- End Set
- End Property
- Protected Overrides Sub CreateChildControls()
- Controls.Clear()
- _owner = New TemplateOwner()
- Dim temp As ITemplate = _template
- If temp Is Nothing Then
- temp = New DefaultTemplate
- End If
- temp.InstantiateIn(_owner)
- Me.Controls.Add(_owner)
- End Sub
- Public Overrides Sub DataBind()
- If Not ChildControlsCreated Then
- CreateChildControls()
- ChildControlsCreated = True
- End If
- MyBase.DataBind()
- End Sub
- Protected Overrides Sub Finalize()
- MyBase.Finalize()
- End Sub
- Private Sub SmartFilter_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
- 'This is where all the logic resides
- 'If this is NOT a post back we are getting values from session, we will have to change the code to read values from database instead
- 'the database will have 5 columns FormId, Control Id, control type, control value and user id
- 'For the logged in user (get user id from the context like grid control). Pass the user id and form id to the database which will return
- ' 3 columns control id, control type and control value for selected combination
- 'then loop through the code to read the values from databaset and load them into control. This code is already there.
- 'If this is a post back then we need to loop through the controls, read the user selections and send them to database for storing into
- 'profile table so that they can be loaded next time.
- If Not Me.Page.IsPostBack Then
- LoadControlValuesFromProfile()
- Else
- StoreControlValuesToProfile()
- End If
- End Sub
- ' This part of the code can have some more improvements, this can be modified to make sure that the post back done by the page was initiated by search
- ' button and not some other event. This way we will not store the user's filter criteria on each post back and we can save it only when search is
- ' clicked when there is chance of user changing his search parameters. As soon as this part is done I'll send you guys new code.
- ' For now the code will work even without this in place just that for each post back we will make a call to database and store the search criterias
- ' for the user
- Private Function GetPostBackControl(ByVal page As Page) As Control
- Dim postbackControlInstance As Control = Nothing
- Dim postbackControlName As String = page.Request.Params.[Get]("__EVENTTARGET")
- If postbackControlName <> Nothing AndAlso postbackControlName <> String.Empty Then
- postbackControlInstance = page.FindControl(postbackControlName)
- Else
- ' handle the Button control postbacks
- Dim i As Integer = 0
- While i < page.Request.Form.Keys.Count
- postbackControlInstance = page.FindControl(page.Request.Form.Keys(i))
- If TypeOf postbackControlInstance Is System.Web.UI.WebControls.Button Then
- Return postbackControlInstance
- End If
- System.Math.Max(System.Threading.Interlocked.Increment(i), i - 1)
- End While
- End If
- ' handle the ImageButton postbacks
- If postbackControlInstance Is Nothing Then
- Dim i As Integer = 0
- While i < page.Request.Form.Count
- If (page.Request.Form.Keys(i).EndsWith(".x")) OrElse (page.Request.Form.Keys(i).EndsWith(".y")) Then
- postbackControlInstance = page.FindControl(page.Request.Form.Keys(i).Substring(0, page.Request.Form.Keys(i).Length - 2))
- Return postbackControlInstance
- End If
- System.Math.Max(System.Threading.Interlocked.Increment(i), i - 1)
- End While
- End If
- Return postbackControlInstance
- End Function
- Private Sub LoadControlValuesFromProfile()
- If Not IsNothing(HttpContext.Current.Session(Me.Page.Form.ID)) Then
- ' If child controls are not created yet then create.
- If Not ChildControlsCreated Then
- CreateChildControls()
- ChildControlsCreated = True
- End If
- ' Get value from datasource for filter control.
- Dim objArray As ArrayList
- objArray = CType(HttpContext.Current.Session(Me.Page.Form.ID), ArrayList)
- For Each objControl In objArray
- Dim objControlInfo As ArrayList = CType(objControl, ArrayList)
- ' populate filter control with history data.
- Select Case objControlInfo(0).ToString
- Case "textbox"
- CType(_owner.FindControl(objControlInfo(1).ToString), TextBox).Text = objControlInfo(2).ToString
- Case "dropdownlist"
- CType(_owner.FindControl(objControlInfo(1).ToString), DropDownList).SelectedValue = objControlInfo(2).ToString
- Case "checkbox"
- CType(_owner.FindControl(objControlInfo(1).ToString), CheckBox).Checked = CType(objControlInfo(2).ToString, Boolean)
- Case "radiobutton"
- CType(_owner.FindControl(objControlInfo(1).ToString), RadioButton).Checked = CType(objControlInfo(2).ToString, Boolean)
- Case Else
- ' Do nothing.
- End Select
- Next
- End If
- End Sub
- Private Sub StoreControlValuesToProfile()
- ' Insert data into datasource from filter control.
- Dim objArray As New ArrayList
- For Each objControl In _owner.Controls
- Dim objControlInfo As New ArrayList
- Select Case objControl.GetType.Name.ToLower()
- Case "textbox"
- objControlInfo.Add("textbox")
- objControlInfo.Add(CType(objControl, WebControl).ID)
- objControlInfo.Add(CType(objControl, TextBox).Text)
- Case "dropdownlist"
- objControlInfo.Add("dropdownlist")
- objControlInfo.Add(CType(objControl, WebControl).ID)
- objControlInfo.Add(CType(objControl, DropDownList).SelectedValue)
- Case "checkbox"
- objControlInfo.Add("checkbox")
- objControlInfo.Add(CType(objControl, WebControl).ID)
- objControlInfo.Add(CType(objControl, CheckBox).Checked.ToString)
- Case "radiobutton"
- objControlInfo.Add("radiobutton")
- objControlInfo.Add(CType(objControl, WebControl).ID)
- objControlInfo.Add(CType(objControl, RadioButton).Checked.ToString)
- Case Else
- ' Do nothing
- End Select
- If objControlInfo.Count <> 0 Then
- objArray.Add(objControlInfo)
- End If
- Next
- HttpContext.Current.Session(Me.Page.Form.ID) = objArray
- End Sub
- End Class
- <ToolboxItem(False)> _
- Public Class TemplateOwner
- Inherits WebControl
- End Class
- #Region "DefaultTemplate"
- NotInheritable Class DefaultTemplate
- Implements ITemplate
- Sub InstantiateIn(ByVal owner As Control) _
- Implements ITemplate.InstantiateIn
- Dim title As New Label
- AddHandler title.DataBinding, AddressOf title_DataBinding
- Dim linebreak As New LiteralControl("<br/>")
- Dim caption As New Label
- AddHandler caption.DataBinding, _
- AddressOf caption_DataBinding
- owner.Controls.Add(title)
- owner.Controls.Add(linebreak)
- owner.Controls.Add(caption)
- For Each objControl In owner.Controls
- ' = objControl.ToString
- Next
- End Sub
- Sub caption_DataBinding(ByVal sender As Object, _
- ByVal e As EventArgs)
- Dim source As Label = CType(sender, Label)
- Dim container As SmartFilter = _
- CType(source.NamingContainer, SmartFilter)
- source.Text = container.Caption
- End Sub
- Sub title_DataBinding(ByVal sender As Object, _
- ByVal e As EventArgs)
- Dim source As Label = CType(sender, Label)
- Dim container As SmartFilter = _
- CType(source.NamingContainer, SmartFilter)
- source.Text = container.Caption
- End Sub
- End Class
- #End Region
- Public Class SmartFilterDesigner
- Inherits ControlDesigner
- Public Overrides Sub Initialize(ByVal Component As IComponent)
- MyBase.Initialize(Component)
- SetViewFlags(ViewFlags.TemplateEditing, True)
- End Sub
- Public Overloads Overrides Function GetDesignTimeHtml() As String
- Return "<span>This is design-time HTML</span>"
- End Function
- Public Overrides ReadOnly Property TemplateGroups() As TemplateGroupCollection
- Get
- Dim collection As New TemplateGroupCollection
- Dim group As TemplateGroup
- Dim template As TemplateDefinition
- Dim control As SmartFilter
- control = CType(Component, SmartFilter)
- group = New TemplateGroup("Item")
- template = New TemplateDefinition(Me, "Template", control, "Template", True)
- group.AddTemplateDefinition(template)
- collection.Add(group)
- Return collection
- End Get
- End Property
- End Class
现在该服务器控件就创建完成了,接下来就是怎么使用他了.
三.使用该控件.
比如有个查询页面叫search.aspx,该页面是提供给客户查询信息的,里面假如有一些提供查询条件的服务器控件,比如TEXTBOX,RADIOBUTTON,DROPDOWNLIST,CHECKBOX.将该控件拖到search.aspx活动页面文件,点击该控件的"Edit Templates"属性,将TEXTBOX,RADIOBUTTON,DROPDOWNLIST,CHECKBOX控件放入Templates中,也可以通过页面前端代码加入:比如
<cc1:SmartFilter ID="SmartFilter1" runat="server">
<Template>
<asp:Label ID="Label3" runat="server" Text="Textbox"></asp:Label>
<asp:TextBox ID="Txt1" runat="server"></asp:TextBox>
<asp:DropDownList ID="DropDownList1" runat="server">
<asp:ListItem Text="East" Value="east" Selected="True"></asp:ListItem>
<asp:ListItem Text="West" Value="west"></asp:ListItem>
<asp:ListItem Text="South" Value="south"></asp:ListItem>
<asp:ListItem Text="North" Value="north"></asp:ListItem>
</asp:DropDownList>
<asp:CheckBox ID="CheckBox1" runat="server" Text="Is this a cool code" Checked="true"/>
<asp:RadioButton ID="RadioButton1" runat="server" Text="Radio Button"/>
<asp:Button ID="Button3" runat="server" Text="Button" onclick="Button3_Click" />
</Template>
</cc1:SmartFilter>
好了,就是这样了,懒地写了,还没吃早饭,有问题的可以直接问我,联系方式BLOG上有