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. |