Binding to the DataList
Now that we have the Contact and Contacts classes and the DataList is properly defined, we can write the code that supports displaying and editing the values presented in the web page. Listing 3 provides the complete listing for the DataList sample application. (It's important to note that the web form designer code was concealed. Create an ASP.NET web application and then copy the code in Listing 3 to the web form.)
Listing 3The Code-Behind Listing for the DataList Example
1: Imports Data 2: 3: Public Class WebForm1 4: Inherits System.Web.UI.Page 5: Protected WithEvents Button1 As _ 6: System.Web.UI.WebControls.Button 7: 8: [ Web Form Designer Generated Code ] 9: 10: Private FContacts As Contacts 11: 12: Private Sub Page_Load(ByVal sender _ 13: As System.Object, ByVal e As System.EventArgs) _ 14: Handles MyBase.Load 15: 16: If (Session("Contacts") Is Nothing) Then 17: FContacts = New Contacts() 18: Session("Contacts") = FContacts 19: Else 20: FContacts = CType(Session("Contacts"), Contacts) 21: End If 22: 23: If (Not IsPostBack) Then 24: BindData() 25: End If 26: End Sub 27: 28: Private Function IsEmpty() As Boolean 29: Return FContacts.Items.Count = 0 30: End Function 31: 32: Private Function GetLast() As Contact 33: Return FContacts.Items(FContacts.Items.Count - 1) 34: End Function 35: 36: Private Function HasNewItem() As Boolean 37: If (Not IsEmpty()) Then 38: Return GetLast().FirstName = "" 39: Else 40: Return False 41: End If 42: End Function 43: 44: Private Sub BindData() 45: If (HasNewItem() = False) Then 46: FContacts.Items.Add(New Contact()) 47: End If 48: 49: DataList1.DataSource = FContacts.Items 50: DataList1.DataBind() 51: End Sub 52: 53: Private Sub DataList1_EditCommand(ByVal source As Object, _ 54: ByVal e As System.Web.UI.WebControls.DataListCommandEventArgs) _ 55: Handles DataList1.EditCommand 56: 57: DataList1.EditItemIndex = CInt(e.Item.ItemIndex) 58: BindData() 59: End Sub 60: 61: Private Sub DataList1_UpdateCommand(ByVal source As Object, _ 62: ByVal e As System.Web.UI.WebControls.DataListCommandEventArgs) _ 63: Handles DataList1.UpdateCommand 64: 65: Dim Contact As Contact = FContacts.Items(e.Item.ItemIndex) 66: 67: Contact.FirstName = CType(e.Item.FindControl("TextBox1"), TextBox).Text 68: Contact.LastName = CType(e.Item.FindControl("TextBox2"), TextBox).Text 69: Contact.EMail = CType(e.Item.FindControl("TextBox3"), TextBox).Text 70: Contact.URL = CType(e.Item.FindControl("TextBox4"), TextBox).Text 71: 72: DataList1.EditItemIndex = -1 73: BindData() 74: End Sub 75: 76: Private Sub DataList1_CancelCommand(ByVal source As Object, _ 77: ByVal e As System.Web.UI.WebControls.DataListCommandEventArgs) _ 78: Handles DataList1.CancelCommand 79: 80: DataList1.EditItemIndex = -1 81: BindData() 82: End Sub 83: 84: Private Sub DataList1_DeleteCommand(ByVal source As Object, _ 85: ByVal e As System.Web.UI.WebControls.DataListCommandEventArgs) _ 86: Handles DataList1.DeleteCommand 87: 88: Try 89: FContacts.Items.Remove(FContacts.Items(e.Item.ItemIndex)) 90: Finally 91: DataList1.EditItemIndex = -1 92: BindData() 93: End Try 94: 95: End Sub 96: End Class
The code designer was used to generate event methods for the form and the DataList. The Page_Load, DataList1_EditCommand, Datalist1_UpdateCommand, DataList1_CancelCommand, and DataList1_DeleteCommand event handlers were generated to support creating the Contacts object and responding to the four LinkButton commands: Edit, Update, Delete, and Cancel. When the page is loaded or refreshed, the Page_Load event handler code runs. When you click any of the LinkButton controls, the associated event handler code runs. For example, clicking the Edit LinkButton runs the DataList1_EditCommand.
Page Load Event
The Page_Load event code checks whether anything has been tucked into the Session cache. This technique can be used to determine whether the Contacts object has been created. If the object cannot be found in the Session cache, we need to create the Contacts object and put it in the cache. This occurs on lines 1618 of Listing 3. If we have loaded the page at least once already, the Contacts object is retrieved from the cache rather than re-created. Keep in mind that we have to store the object somewhere; otherwise, the object state is not maintained between trips to and from the web server.
Line 23 checks whether this is a post back to the web server. If not, BindData is invoked to re-create the view of the DataList. BindData, on lines 4451, was implemented to ensure that we always have a blank object to modify in our web page. On line 49 we set the Datalist1.DataSource property to the Items property of our Contacts object and invoke DataList1.DataBind to render the page.
Edit Command Event
When a user clicks the LinkButton that has the CommandName="edit" value, the DataList1_EditCommand event handler code runs. The EditCommand handler assigns the DataList1.EditItemIndex equal to the index of the selected item. The index is retrieved from a property of the DataListCommandEventArgs (see lines 5354).
Changing the EditItemIndex to a positive integer places the DataList in edit mode. When we invoke BindData in edit mode, the DataList is rendered as described in the EditItemTemplate.
Cancel Command Event
The CancelCommand event handler is defined on lines 7682. By setting the DataList1.EditItemIndex to -1 we effectively place the DataList back into browse mode. Binding the data renders the DataList as described in the ItemTemplate.
Delete Command Event
The DeleteCommand event handler is implemented to delete the currently selected item. Line 89 removes the Contact item from the list of contacts. Line 91 performs the same operation as the CancelCommand: the DataList is placed back into browse mode and we rebind the DataList control.
Update Command Event
The UpdateCommand is the most complex event handler. To update the state of the FContacts object, we need to read the value of the text boxes from the row we're editing in the DataList.
Updating occurs on lines 6174. The first thing we do is get the index of the item we're currently editing and use that index to get a reference to the Contact item associated with this index. Then, on lines 6770, we read each of the values from the TextBox controls, place the DataList in browse mode, and rebind.
Unfortunately, getting data out of the DataList is a little convoluted. Using line 67 as an example, the e.Item property is a DataListItem object. The DataListItem.FindControl method finds an identified control defined in that DataListItemthink row. (Keep in mind that you only defined a template; each DataListItem and the controls in that item were automatically created by the DataList.) The code dynamically casts the control to its real type, a TextBox, using the CType method, and the value is retrieved from the TextBox and assign to the Contact property.