Asp.NET Tutorials
Home > Asp.Net开发 > How to embed UpdatePanel in a Repeater

Hot archives

How to embed UpdatePanel in a Repeater
Author:Daron Yöndem.

Introduction

i was working on a project where I needed to use a repeater to list some records. Repeater is the most flexible tool when advanced UI and record editing options are needed. In order to provide rich user experience I decided to use Microsoft ASP.NET AJAX Extension library, actually meaning UpdatePanel. My main purpose is to provide an UpdatePanel for each record in Repeater. The user will be able to edit any record listed in Repeater but only edited records information will be refreshed in its own UpdatePanel. Additionally Repeater control will be in an extra UpdatePanel in order to populate Repeater without full page refresh.

in summary;

  • Repeater will be populated inside UpdatePanel
  • Each Repeater Item will contain an independent UpdatePanel.
  • Each record in repeater will be edited without full page or full repeater refresh.

Mark Up Code

<asp:UpdatePanel ID="UpdatePanel1" 
runat="server" UpdateMode="Conditional"> <ContentTemplate> <asp:Repeater ID="Repeater1" runat="server"> <ItemTemplate> <asp:UpdatePanel UpdateMode="Conditional" ID="UpdatePanel2" runat="server"> <ContentTemplate> <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox> <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label> <asp:Button ID="Button2" runat="server" Text="Button" /> </ContentTemplate> </asp:UpdatePanel> </ItemTemplate> </asp:Repeater> <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" /> </ContentTemplate> </asp:UpdatePanel>

in our Mark-Up code we have an UpdatePanel inside ContentTemplate of Repeater control. The main repeater control is in another UpdatePanel as well. The inner updatepanel with ID "UpdatePanel2" will be repeated for each item of Repeater1.

we will need some dummy data to populate our Repeater control. The code below is just creating a table with dummy data and binding it to Repeater.

   Protected Sub Button1_Click(
ByVal sender As Object, ByVal
e As System.EventArgs) Dim mytable As New Data.DataTable Dim mycolumn As New Data.DataColumn
("MyData") mytable.Columns.Add(mycolumn) Dim myrow As Data.DataRow myrow = mytable.NewRow myrow.Item(0) = "Trial Row 1" mytable.Rows.Add(myrow) myrow = mytable.NewRow myrow.Item(0) = "Trial Row 2" mytable.Rows.Add(myrow) myrow = mytable.NewRow myrow.Item(0) = "Trial Row 3" mytable.Rows.Add(myrow) Repeater1.DataSource = mytable Repeater1.DataBind() End Sub

it's time to set up bindings for our Repeater control. Actually there is nothing special here; we are just accessing our UpdatePanel control from inside our Repeater in order to be able to access other controls which are inside UpdatePanels ContentTemplate. Finally we bind data to controls.

Collapse
    Protected Sub Repeater1_ItemDataBound(ByVal sender As Object, 
               ByVal e As
System.Web.UI.WebControls.RepeaterItemEventArgs) Handles Repeater1.ItemDataBound If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then Dim CurrentUpdatePanel As System.Web.UI.UpdatePanel CurrentUpdatePanel= e.Item.FindControl("UpdatePanel2") Dim mylabel As System.Web.UI.WebControls.Label mylabel = CurrentUpdatePanel.FindControl("Label1") Dim mybutton As System.Web.UI.WebControls.Button mybutton = CurrentUpdatePanel.FindControl("Button2") mylabel.Text = e.Item.DataItem.item(0) mybutton.Text = "Update" End If End Sub

The Trick

here comes the tricky part. How we will handle button clicks? Remember, we have a ScriptManager on each AJAX based web page. The role of ScriptManager is to handle all requests etc. Hopefully our populated UpdatePanels should be handled by our ScriptManager as well. That's why we are using ScriptManagers PreRender event. All AJAX based renders on our page will fire this event. But we don't need to handle all renders. We just need the ones coming from our populated UpdatePanels inside Repeater1. In order to get the sender of PreRendering we use AsyncPostBackSourceElementID property of ScriptManager. The source controls rendered ID will contain our Repeaters and Buttons IDs. Additionally it will contain the row number of repeated ItemTemplate inside Repeater. That will be something like Repeater1$ctl01$Button2. After getting the row number from incoming ID we can access all data inside our Repeater. We can save, edit anything to database and let our ScriptManager render UpdatePanel with new values. In our example we are getting the value inside TextBox and transferring it to a Label.

    Protected Sub AnyClick(ByVal sender As Object, 
             ByVal e As System.EventArgs) 
Handles ScriptManager1.PreRender Dim IncID As String IncID = CType(sender, System.Web.UI.ScriptManager) &_ .AsyncPostBackSourceElementID.ToString Dim RowIndex As Integer = 0 If IncID.IndexOf(Repeater1.ID) <> -1 And IncID.IndexOf("Button2") <> -1 Then IncID = IncID.Replace(Repeater1.ID & "$ctl", "") IncID = IncID.Replace("$Button2", "") RowIndex = CInt(IncID) Dim mytextbox As System.Web.UI.WebControls.TextBox mytextbox
= Repeater1.Items(RowIndex).FindControl("Textbox1") Dim mylabel As System.Web.UI.WebControls.Label mylabel = Repeater1.Items(RowIndex).FindControl("label1") mylabel.Text = mytextbox.Text End If End Sub

Inside WebUserControl

what about if we have all those UpdatePanels inside a WebUserControl? The problem is that we will not be able to access ScriptManager component from inside a WebUserControl. However there are always tricks. Let's say we added our WebUserControl to our web page and we have the partial codes below:

<%@ Register Src="WebUserControl.ascx" 
    TagName="WebUserControl" TagPrefix="uc1" %>

<uc1:WebUserControl ID="WebUserControl1" 
runat="server" />

the next step is to set up our WebUserControl to be accessable from Web Form. We will add a property named SManager to our WebUserControl. The property will get our Web Forms ScriptManager1 control and transfer it to the private MainManager variable of WebUserControl.

    Private withevents MainManager As System.Web.UI.ScriptManager

    Public Property SManager() As System.Web.UI.ScriptManager
        Get
            Return MainManager
        End Get
        Set(ByVal value As System.Web.UI.ScriptManager)
            MainManager = value
        End Set
    End Property

now we can set our WebForm to transfer ScriptManager1 control to the WebUserControl. We will add the code below to our WebForms code-behind.

        WebUserControl1.SManager = ScriptManager1

finally we need to set up our PreRender event handler for ScriptManager. The event handler will be placed inside WebUserControl and handled by our private MainManager which is defined with WithEvents keyword inside WebUserControl and which is equal to WebForms ScriptManager through our Smanager property.

    Protected Sub AnyClick(ByVal sender As Object, &_
     ByVal e As System.EventArgs) Handles MainManager.PreRender
        Dim IncID As String
        IncID = CType(sender, System.Web.UI.ScriptManager) &_
        .AsyncPostBackSourceElementID.ToString()
        Dim RowIndex As Integer = 0
        If IncID.IndexOf(Repeater1.ID) <> -1 And &_
        IncID.IndexOf("Button2") <> -1 Then
            IncID = IncID.Replace(Repeater1.ID & "$ctl", "")
            IncID = IncID.Replace("$Button2", "")
            IncID = IncID.Replace("WebUserControl1$", "")
            RowIndex = CInt(IncID)
            Dim mytextbox As System.Web.UI.WebControls.TextBox
            mytextbox 
= Repeater1.Items(RowIndex).FindControl("Textbox1") Dim mylabel As System.Web.UI.WebControls.Label mylabel = Repeater1.Items(RowIndex).FindControl("label1") mylabel.Text = mytextbox.Text End If End Sub

when clearing the incomming AsyncPostBackSourceElementID to get RowIndex I added one extra line of code to erase WebUserControls ID.

The Conclusion

now you have got a web page that never gets fully refreshed. You can populate the repeater without full page refresh and edit, save all records without even full repeater refresh. Finally I would like to remind you to not forget to set UpdateMode properties of UpdatePanels to "Conditional".

About Daron Yöndem


Daron Yöndem has been a professional web developer since 2002 and Windows Interface developer since 1998, and is working with VB.NET and ASP.Net since early 2002. He has been working with VB 3.0, 4.0 and 6.0 since 1998.

He is the founder of DEVELOAD Software & Design, a recognized leader in web-enabled application development with a proven track record in Turkey since 2003. The company is specialized in custom online applications.

Click here to view Daron Yöndem's online profile.

Add by : Huobazi (2007-4-28:04:05)