anti-keseronokan (old)
Fun Stuff for Anti-Fun People
This blog has moved to http://ikhwanhayat.net
Monday, November 28, 2005
AddHandler in Data Bound Controls
I have a parent-child kind of data, and to list it I need a DataList with a DataGrid in it's row. Get it? Okay, this looks like a good place to show-off my ASCII arting prowess.
+=DataList==================================+ | Item1 [remove] | | +-DataGrid-------------------------+ | | | Item1.1 [delete] | | | | Item1.2 [delete] | | | | Item1.3 [delete] | | | | Item1.4 [delete] | | | +----------------------------------+ | +===========================================+ | Item2 [remove] | | +-DataGrid-------------------------+ | | | Item2.1 [delete] | | | | Item2.2 [delete] | | | | Item2.3 [delete] | | | +----------------------------------+ | +===========================================+Actually making the data come out like this is not really that hard. Just make an event handler for the ItemDataBound of the DataList, and add codes to DataBind the child rows to the DataGrid. Like so:
Protected dlParent As DataList
Protected ParentTable As DataTable
Protected ChildTable As DataTable
.
.
Private Sub dlParent_ItemDataBound(ByVal sender As Object, _
ByVal e As System.Web.UI.WebControls.DataListItemEventArgs) _
Handles dlParent.ItemDataBound
If (e.Item.ItemType = ListItemType.Item _
OrElse e.Item.ItemType = ListItemType.AlternatingItem) Then
Dim dgChild As DataGrid
dgChild = DirectCast(e.Item.FindControl("dgChild"), DataGrid)
Dim parentID As String
parentID = DirectCast(e.Item.DataItem, DataRowView)("ParentID").ToString()
Dim dv As DataView = ChildTable.DefaultView
dv.RowFilter = "ParentID=" & parentID
dgChild.DataSource = dv
dgChild.DataBind()
End If
End SubThe confusing part is how to handle the event for the [delete] button in the DataGrid. The intention is to delete the particular child item from the ChildTable. The first thing comes into my mind is to dinamically attach an event handler ItemCommand to the DataGrid. So I just make an AddHandler in the dlParent_ItemDataBound, and write the appropriate event handler :
.
' in the dlParent_ItemDataBound
AddHandler dgChild.ItemCommand, AddressOf Child_ItemCommand
.
.
' The event handler
Private Sub Child_ItemCommand(ByVal source As Object, _
ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs)
' Deletion routines here
End SubThis is where I did wrong. I tried this one over and over. Everything seems fine, but the event handler is just not being invoked at all. After some Googling (like always), I came to a solution. What I should do is make the AddHandler in the ItemCreated event, not in the ItemDataBound event. It worked like a charm. Another job (almost) well done.
Thanks to this page, http://www.codecomments.com/archive289-2004-8-268077.html
ItemDataBound isn't invoked on postback because the control isn't databound back to the source, the viewstate is used. If you put a breakpoint/trace in ItemDataBound you'll see it isn't called. handlers added dynamically don't preserve their state on postback, so you need to add them somewhere around the page_load event (not exactly sure what's the latest you can get away with). You can either put the code in the ItemCreated or in Page_Load if Page.IsPostBack is true.

0 Comments:
Post a Comment
<< Home