ridgeway
asked on
VB.Net Event Bubbling with Composite Templated Databound Web Controls
Hi,
I am creating a web control that is comprised of a several controls, one of which includes a databound DataList control. During the databinding process of the DataList control, additional controls are added to the DataList. The DataList control utilizes the .ItemTemplate property to assign a template to each row in the DataList. I am having problems bubbling the events to the parent control.
I have created a simplified version of my scenario to illustrate the issue (below).
In the example the custom control's class is called "MyCustomControl" and the class that handles the item template is called "TemplateDataListItems". The "MyEdit" event is never fired. I'm thinking the issue has something to do with bubbling events from the template class to the control class otherwise the example is very similar to the MSDN developer guide's artical titled "Event Bubbling Control Sample".
Any help on the issue would be greatly appreciated.
Thanks,
Ben
Public Class MyCustomControl
Inherits System.Web.UI.WebControls. WebControl
Implements INamingContainer
Private WithEvents _MyDataList As DataList
Public Event MyEdit As EventHandler
Protected Overridable Sub OnMyEdit(ByVal sender As Object, ByVal e As EventArgs)
RaiseEvent MyEdit(sender, e)
End Sub
Protected Overrides Function OnBubbleEvent(ByVal sender As Object, ByVal e As EventArgs) As Boolean
Dim handled As Boolean = False
If TypeOf e Is CommandEventArgs Then
Dim ce As CommandEventArgs = CType(e, CommandEventArgs)
If (ce.CommandName = "Edit") Then
OnMyEdit(sender, ce)
handled = True
End If
End If
Return handled
End Function
Protected Overrides Sub CreateChildControls()
_MyDataList = New DataList
_MyDataList.ID = Me.UniqueID + "_MyDataList"
_MyDataList.ItemTemplate = new TemplateDataListItems
Controls.Add(_MyDataList)
End Sub
Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs)
'bind to data
Dim MyDataSet As DataSet = '<Get Data here>
_MyDataList.DataSource = MyDataSet
_MyDataList.DataBind()
End Sub
Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWrit er)
_MyDataList.RenderControl( writer)
End Sub
Public Sub ColumnEditClick(ByVal sender As Object, ByVal e As ImageClickEventArgs)
Page.Trace.write("ColumnEd itClick: " + sender.GetType.ToString)
End Sub
Public Sub ColumnInfoClick(ByVal sender As Object, ByVal e As ImageClickEventArgs)
Page.Trace.write("ColumnIn foClick: " + sender.GetType.ToString)
End Sub
End Class
Public Class TemplateDataListItems
Implements ITemplate
Public Sub InstantiateIn(ByVal container As System.Web.UI.Control) Implements System.Web.UI.ITemplate.In stantiateI n
Dim ibEdit As New ImageButton
AddHandler ibEdit.DataBinding, AddressOf BindEdit
container.Controls.Add(ibE dit)
End Sub
Private Sub BindEdit(ByVal sender As Object, ByVal e As EventArgs)
Dim l As ImageButton = sender
Dim container As DataListItem = l.NamingContainer()
l.ID = "ibEdit"
l.CommandName = "Edit"
'<Column From Bound Dataset>
l.CommandArgument = container.DataItem("MyColu mnName")
l.ImageUrl = "/images/myeditbutton.gif"
End Sub
End Class
I am creating a web control that is comprised of a several controls, one of which includes a databound DataList control. During the databinding process of the DataList control, additional controls are added to the DataList. The DataList control utilizes the .ItemTemplate property to assign a template to each row in the DataList. I am having problems bubbling the events to the parent control.
I have created a simplified version of my scenario to illustrate the issue (below).
In the example the custom control's class is called "MyCustomControl" and the class that handles the item template is called "TemplateDataListItems". The "MyEdit" event is never fired. I'm thinking the issue has something to do with bubbling events from the template class to the control class otherwise the example is very similar to the MSDN developer guide's artical titled "Event Bubbling Control Sample".
Any help on the issue would be greatly appreciated.
Thanks,
Ben
Public Class MyCustomControl
Inherits System.Web.UI.WebControls.
Implements INamingContainer
Private WithEvents _MyDataList As DataList
Public Event MyEdit As EventHandler
Protected Overridable Sub OnMyEdit(ByVal sender As Object, ByVal e As EventArgs)
RaiseEvent MyEdit(sender, e)
End Sub
Protected Overrides Function OnBubbleEvent(ByVal sender As Object, ByVal e As EventArgs) As Boolean
Dim handled As Boolean = False
If TypeOf e Is CommandEventArgs Then
Dim ce As CommandEventArgs = CType(e, CommandEventArgs)
If (ce.CommandName = "Edit") Then
OnMyEdit(sender, ce)
handled = True
End If
End If
Return handled
End Function
Protected Overrides Sub CreateChildControls()
_MyDataList = New DataList
_MyDataList.ID = Me.UniqueID + "_MyDataList"
_MyDataList.ItemTemplate = new TemplateDataListItems
Controls.Add(_MyDataList)
End Sub
Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs)
'bind to data
Dim MyDataSet As DataSet = '<Get Data here>
_MyDataList.DataSource = MyDataSet
_MyDataList.DataBind()
End Sub
Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWrit
_MyDataList.RenderControl(
End Sub
Public Sub ColumnEditClick(ByVal sender As Object, ByVal e As ImageClickEventArgs)
Page.Trace.write("ColumnEd
End Sub
Public Sub ColumnInfoClick(ByVal sender As Object, ByVal e As ImageClickEventArgs)
Page.Trace.write("ColumnIn
End Sub
End Class
Public Class TemplateDataListItems
Implements ITemplate
Public Sub InstantiateIn(ByVal container As System.Web.UI.Control) Implements System.Web.UI.ITemplate.In
Dim ibEdit As New ImageButton
AddHandler ibEdit.DataBinding, AddressOf BindEdit
container.Controls.Add(ibE
End Sub
Private Sub BindEdit(ByVal sender As Object, ByVal e As EventArgs)
Dim l As ImageButton = sender
Dim container As DataListItem = l.NamingContainer()
l.ID = "ibEdit"
l.CommandName = "Edit"
'<Column From Bound Dataset>
l.CommandArgument = container.DataItem("MyColu
l.ImageUrl = "/images/myeditbutton.gif"
End Sub
End Class
ASKER
Ahh, finally someone that really knows what they are talking about!
I did forget to handle the DataList's ItemDataBound event.
I am however, now having issues with accessing the control. Since the ibEdit control is not actually the only one I am attempting to access it using the FindControl Method rather than using e.Item.Controls(X) for clarity sake. When my code executes I get the "Object reference not set to an instance of an object", I did a trace and found that the e.Item.Controls.Count = 0 at this point. Any ideas?
If (e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingIt em) Then
Dim ibEdit As ImageButton = DirectCast(e.Item.FindCont rol("ibEdi t"), ImageButton)
AddHandler ibEdit.Command, AddressOf OnColumnEdit
End if
Thanks,
Ben
I did forget to handle the DataList's ItemDataBound event.
I am however, now having issues with accessing the control. Since the ibEdit control is not actually the only one I am attempting to access it using the FindControl Method rather than using e.Item.Controls(X) for clarity sake. When my code executes I get the "Object reference not set to an instance of an object", I did a trace and found that the e.Item.Controls.Count = 0 at this point. Any ideas?
If (e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingIt
Dim ibEdit As ImageButton = DirectCast(e.Item.FindCont
AddHandler ibEdit.Command, AddressOf OnColumnEdit
End if
Thanks,
Ben
Yeah most of the "experts" on this site are good at helping the newbies but crack on the advanced discussions. Whenever I have a real question I post it over on asp.net/forums or the microsoft newsgroups. The MVP's hang out there, not here...
--
Interesting I don't have that problem with the sample you first posted, I could access the itemtemplate/controls within it without a problem when the DataList fired ItemDataBound/ItemCreated. Perhaps some inconsistencies between your simplified version and what you really have? The only thing I can guess is you aren't adding the template to the container in InstantiateIn().
--Michael
--
Interesting I don't have that problem with the sample you first posted, I could access the itemtemplate/controls within it without a problem when the DataList fired ItemDataBound/ItemCreated.
--Michael
ASKER
The code will not throw any errors if I access the controls by index:
e.Item.Controls(3)
however if I try by ID such as:
e.Item.FindControl("ibEdit ")
then I get an error. For now I have my controls set up to be accessed by index and can deal with that issue later.
Now that I have added the code in ItemsCreated I still can not get the events to fire.
Any more ideas?
e.Item.Controls(3)
however if I try by ID such as:
e.Item.FindControl("ibEdit
then I get an error. For now I have my controls set up to be accessed by index and can deal with that issue later.
Now that I have added the code in ItemsCreated I still can not get the events to fire.
Any more ideas?
ASKER
Oh, wait. I just realized that I am adding handlers for the Command event and not the Click event. When I click on the Image Button should it raise both the Click & Command event or just the Click event? Do I need to figure out a way to bubble the click event to the Command event of the DataList?
I can get the ItemCommand of the DataList to fire for the ImageButton, have you tried handling that?. One thing I can't seem to do is get my own custom event handler to fire for the ImageButtons (Don't know why, I added a handler correctly)
ASKER
OK, I have set aside the actual problem and have created a working example but I still can not get the events to fire.
Do you see what I am doing wrong. Does your working example look like this one?
I now have a test.aspx page:
<form id="Form1" method="post" runat="server">
<cc1:MyCustomControl id="MyCustomControl1" runat="server" TableName="test"></cc1:MyC ustomContr ol>
</form>
And a MyCustomControl.vb:
Imports System.ComponentModel
Imports System.Web.UI
Imports System.Web.UI.WebControls
Public Class MyCustomControl
Inherits System.Web.UI.WebControls. WebControl
Implements INamingContainer
Private WithEvents _MyDataList As DataList
Public Event MyEdit As EventHandler
Protected Overridable Sub OnMyEdit(ByVal sender As Object, ByVal e As CommandEventArgs) ' EventArgs)
Page.Trace.Write("OnMyEdit called")
RaiseEvent MyEdit(sender, e)
End Sub
Protected Overrides Function OnBubbleEvent(ByVal sender As Object, ByVal e As EventArgs) As Boolean
Page.Trace.Write("OnBubble Event called")
Dim handled As Boolean = False
If TypeOf e Is CommandEventArgs Then
Dim ce As CommandEventArgs = CType(e, CommandEventArgs)
If (ce.CommandName = "Edit") Then
OnMyEdit(sender, ce)
handled = True
End If
End If
Return handled
End Function
Protected Overrides Sub CreateChildControls()
_MyDataList = New DataList
_MyDataList.ID = Me.UniqueID + "_MyDataList"
_MyDataList.ItemTemplate = New TemplateDataListItems
Controls.Add(_MyDataList)
End Sub
Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs)
'bind to data
Dim MyDataSet As DataSet = getSomeData
_MyDataList.DataSource = MyDataSet
_MyDataList.DataBind()
End Sub
Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWrit er)
_MyDataList.RenderControl( writer)
End Sub
Private ReadOnly Property getSomeData() As DataSet
Get
Dim ds As New DataSet
ds.Tables.Add("Table1")
ds.Tables(0).Columns.Add(" MyColName" )
For i As Integer = 0 To 4
Dim dr As DataRow = ds.Tables(0).NewRow
dr.Item("MyColName") = "Item " + i.ToString
ds.Tables(0).Rows.Add(dr)
Next
Return ds
End Get
End Property
Private Sub _MyDataList_ItemCreated(By Val sender As Object, ByVal e As System.Web.UI.WebControls. DataListIt emEventArg s) Handles _MyDataList.ItemCreated
If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingIt em Then
Dim ib As ImageButton = DirectCast(e.Item.Controls (0), ImageButton)
AddHandler ib.Command, AddressOf OnMyEdit
End If
End Sub
'Private Sub _MyDataList_ItemCommand(By Val source As Object, ByVal e As System.Web.UI.WebControls. DataListCo mmandEvent Args) Handles _MyDataList.ItemCommand
'End Sub
End Class
Public Class TemplateDataListItems
Implements ITemplate
Public Sub InstantiateIn(ByVal container As System.Web.UI.Control) Implements System.Web.UI.ITemplate.In stantiateI n
Dim ibEdit As New ImageButton
AddHandler ibEdit.DataBinding, AddressOf BindEdit
container.Controls.Add(ibE dit)
End Sub
Private Sub BindEdit(ByVal sender As Object, ByVal e As EventArgs)
Dim l As ImageButton = sender
Dim container As DataListItem = l.NamingContainer()
l.ID = "ibEdit"
l.CommandName = "Edit"
l.CommandArgument = container.DataItem("MyColN ame")
l.ImageUrl = "/noimage.gif"
End Sub
End Class
Do you see what I am doing wrong. Does your working example look like this one?
I now have a test.aspx page:
<form id="Form1" method="post" runat="server">
<cc1:MyCustomControl id="MyCustomControl1" runat="server" TableName="test"></cc1:MyC
</form>
And a MyCustomControl.vb:
Imports System.ComponentModel
Imports System.Web.UI
Imports System.Web.UI.WebControls
Public Class MyCustomControl
Inherits System.Web.UI.WebControls.
Implements INamingContainer
Private WithEvents _MyDataList As DataList
Public Event MyEdit As EventHandler
Protected Overridable Sub OnMyEdit(ByVal sender As Object, ByVal e As CommandEventArgs) ' EventArgs)
Page.Trace.Write("OnMyEdit
RaiseEvent MyEdit(sender, e)
End Sub
Protected Overrides Function OnBubbleEvent(ByVal sender As Object, ByVal e As EventArgs) As Boolean
Page.Trace.Write("OnBubble
Dim handled As Boolean = False
If TypeOf e Is CommandEventArgs Then
Dim ce As CommandEventArgs = CType(e, CommandEventArgs)
If (ce.CommandName = "Edit") Then
OnMyEdit(sender, ce)
handled = True
End If
End If
Return handled
End Function
Protected Overrides Sub CreateChildControls()
_MyDataList = New DataList
_MyDataList.ID = Me.UniqueID + "_MyDataList"
_MyDataList.ItemTemplate = New TemplateDataListItems
Controls.Add(_MyDataList)
End Sub
Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs)
'bind to data
Dim MyDataSet As DataSet = getSomeData
_MyDataList.DataSource = MyDataSet
_MyDataList.DataBind()
End Sub
Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWrit
_MyDataList.RenderControl(
End Sub
Private ReadOnly Property getSomeData() As DataSet
Get
Dim ds As New DataSet
ds.Tables.Add("Table1")
ds.Tables(0).Columns.Add("
For i As Integer = 0 To 4
Dim dr As DataRow = ds.Tables(0).NewRow
dr.Item("MyColName") = "Item " + i.ToString
ds.Tables(0).Rows.Add(dr)
Next
Return ds
End Get
End Property
Private Sub _MyDataList_ItemCreated(By
If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingIt
Dim ib As ImageButton = DirectCast(e.Item.Controls
AddHandler ib.Command, AddressOf OnMyEdit
End If
End Sub
'Private Sub _MyDataList_ItemCommand(By
'End Sub
End Class
Public Class TemplateDataListItems
Implements ITemplate
Public Sub InstantiateIn(ByVal container As System.Web.UI.Control) Implements System.Web.UI.ITemplate.In
Dim ibEdit As New ImageButton
AddHandler ibEdit.DataBinding, AddressOf BindEdit
container.Controls.Add(ibE
End Sub
Private Sub BindEdit(ByVal sender As Object, ByVal e As EventArgs)
Dim l As ImageButton = sender
Dim container As DataListItem = l.NamingContainer()
l.ID = "ibEdit"
l.CommandName = "Edit"
l.CommandArgument = container.DataItem("MyColN
l.ImageUrl = "/noimage.gif"
End Sub
End Class
ASKER
In the example I am trying to get the custom handler working. How did you get the ItemCommand of the DataList to fire for the ImageButton? That may be a more intuitive approach because I can capture and call custom events from there.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks for your help! I learned a lot creating my first databound control.
I got my own events to fire by raising them from the ItemCommand of the DataList. I was also able to move all the logic for the CommandName and CommandArgument settings into the databinding statements so that there is no longer a need to use the ItemCreated event or to reference the controls by index. I added an extra button to the example to better illustrate how to fire custom events based on the CommandName. The only thing that I need to figure out is how to get the Postback / viewstate working properly so that we don't have to load data every time.
-------------------------- ----------
-- Test Page (aspx)
<form id="Form1" method="post" runat="server">
<asp:Label id="Label1" runat="server">Message</as p:Label>
<cc1:MyCustomControl id="MyCustomControl1" runat="server"
TableName="test"></cc1:MyC ustomContr ol>
</form>
-------------------------- ----------
-- Test Page (.vb)
Public Class test
Inherits System.Web.UI.Page
Private Sub MyCustomControl1_EditClick ed(ByVal ArgumentData As String) _
Handles MyCustomControl1.EditClick ed
Me.Label1.Text = "Edit Clicked: " + ArgumentData
End Sub
Private Sub MyCustomControl1_DeleteCli cked(ByVal ArgumentData As String) _
Handles MyCustomControl1.DeleteCli cked
Me.Label1.Text = "Delete Clicked: " + ArgumentData
End Sub
End Class
-------------------------- ----------
-- Custom Control Class
Imports System.ComponentModel
Imports System.Web.UI
Imports System.Web.UI.WebControls
Public Class MyCustomControl
Inherits System.Web.UI.WebControls. WebControl
Implements INamingContainer
Private WithEvents _MyDataList As DataList
'Custom Events that MyCustomControl Raises
Public Event EditClicked(ByVal ArgumentData As String)
Public Event DeleteClicked(ByVal ArgumentData As String)
Public Enum CommandNames As Integer
Edit
Delete
End Enum
Public Property DataSource() As Object
Get
Return _MyDataList.DataSource
End Get
Set(ByVal Value As Object)
_MyDataList.DataSource = Value
End Set
End Property
Public Overrides Sub DataBind()
If Not DataSource Is Nothing Then
_MyDataList.DataBind()
End If
End Sub
Protected Overrides Sub CreateChildControls()
_MyDataList = New DataList
_MyDataList.ID = Me.UniqueID + "_MyDataList"
_MyDataList.ItemTemplate = New TemplateDataListItems
Controls.Add(_MyDataList)
End Sub
Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
MyBase.OnInit(e)
EnsureChildControls()
'(Normally handled in Page - here to simplify)
'If Not Page.IsPostBack Then
Me.DataSource = getADataSet
Me.DataBind()
'End If
End Sub
Private Sub _MyDataList_ItemCommand(By Val source As Object, ByVal e As System.Web.UI.WebControls. DataListCo mmandEvent Args) Handles _MyDataList.ItemCommand
Page.Trace.Write("ItemComm and fired")
Page.Trace.Write("Source Type=" + source.GetType.ToString)
Page.Trace.Write("CommandN ame=" + e.CommandName)
Select Case e.CommandName
Case Me.CommandNames.Edit.ToStr ing
RaiseEvent EditClicked(e.CommandArgum ent)
Case Me.CommandNames.Delete.ToS tring
RaiseEvent DeleteClicked(e.CommandArg ument)
End Select
End Sub
'Used for an example dataset (normally obtained externally)
Private ReadOnly Property getADataSet() As DataSet
Get
Page.Trace.Write("getAData Set called")
Dim ds As New DataSet
ds.Tables.Add("Table1")
ds.Tables(0).Columns.Add(" ArgumentDa ta")
ds.Tables(0).Columns.Add(" AlternateT extData")
For i As Integer = 0 To 2
Dim dr As DataRow = ds.Tables(0).NewRow
dr.Item("ArgumentData") = "Item " + i.ToString
dr.Item("AlternateTextData ") = "This is Item " + i.ToString
ds.Tables(0).Rows.Add(dr)
Next
Return ds
End Get
End Property
End Class
Public Class TemplateDataListItems
Implements ITemplate
Public Sub InstantiateIn(ByVal container As System.Web.UI.Control) Implements System.Web.UI.ITemplate.In stantiateI n
Dim ibEdit As New ImageButton
AddHandler ibEdit.DataBinding, AddressOf BindEdit
container.Controls.Add(ibE dit)
Dim ibDelete As New ImageButton
AddHandler ibDelete.DataBinding, AddressOf BindDelete
container.Controls.Add(ibD elete)
End Sub
Private Sub BindEdit(ByVal sender As Object, ByVal e As EventArgs)
Dim l As ImageButton = sender
Dim container As DataListItem = l.NamingContainer()
l.ID = "ibEdit"
l.CommandName = MyCustomControl.CommandNam es.Edit.To String
l.AlternateText = "Edit (" + container.DataItem("Altern ateTextDat a") + ")"
l.CommandArgument = container.DataItem("Argume ntData")
l.ImageUrl = "/noimage.gif"
End Sub
Private Sub BindDelete(ByVal sender As Object, ByVal e As EventArgs)
Dim l As ImageButton = sender
Dim container As DataListItem = l.NamingContainer()
l.ID = "ibDelete"
l.CommandName = MyCustomControl.CommandNam es.Delete. ToString
l.AlternateText = "Delete (" + container.DataItem("Altern ateTextDat a") + ")"
l.CommandArgument = container.DataItem("Argume ntData")
l.ImageUrl = "/noimage.gif"
End Sub
End Class
I got my own events to fire by raising them from the ItemCommand of the DataList. I was also able to move all the logic for the CommandName and CommandArgument settings into the databinding statements so that there is no longer a need to use the ItemCreated event or to reference the controls by index. I added an extra button to the example to better illustrate how to fire custom events based on the CommandName. The only thing that I need to figure out is how to get the Postback / viewstate working properly so that we don't have to load data every time.
--------------------------
-- Test Page (aspx)
<form id="Form1" method="post" runat="server">
<asp:Label id="Label1" runat="server">Message</as
<cc1:MyCustomControl id="MyCustomControl1" runat="server"
TableName="test"></cc1:MyC
</form>
--------------------------
-- Test Page (.vb)
Public Class test
Inherits System.Web.UI.Page
Private Sub MyCustomControl1_EditClick
Handles MyCustomControl1.EditClick
Me.Label1.Text = "Edit Clicked: " + ArgumentData
End Sub
Private Sub MyCustomControl1_DeleteCli
Handles MyCustomControl1.DeleteCli
Me.Label1.Text = "Delete Clicked: " + ArgumentData
End Sub
End Class
--------------------------
-- Custom Control Class
Imports System.ComponentModel
Imports System.Web.UI
Imports System.Web.UI.WebControls
Public Class MyCustomControl
Inherits System.Web.UI.WebControls.
Implements INamingContainer
Private WithEvents _MyDataList As DataList
'Custom Events that MyCustomControl Raises
Public Event EditClicked(ByVal ArgumentData As String)
Public Event DeleteClicked(ByVal ArgumentData As String)
Public Enum CommandNames As Integer
Edit
Delete
End Enum
Public Property DataSource() As Object
Get
Return _MyDataList.DataSource
End Get
Set(ByVal Value As Object)
_MyDataList.DataSource = Value
End Set
End Property
Public Overrides Sub DataBind()
If Not DataSource Is Nothing Then
_MyDataList.DataBind()
End If
End Sub
Protected Overrides Sub CreateChildControls()
_MyDataList = New DataList
_MyDataList.ID = Me.UniqueID + "_MyDataList"
_MyDataList.ItemTemplate = New TemplateDataListItems
Controls.Add(_MyDataList)
End Sub
Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
MyBase.OnInit(e)
EnsureChildControls()
'(Normally handled in Page - here to simplify)
'If Not Page.IsPostBack Then
Me.DataSource = getADataSet
Me.DataBind()
'End If
End Sub
Private Sub _MyDataList_ItemCommand(By
Page.Trace.Write("ItemComm
Page.Trace.Write("Source Type=" + source.GetType.ToString)
Page.Trace.Write("CommandN
Select Case e.CommandName
Case Me.CommandNames.Edit.ToStr
RaiseEvent EditClicked(e.CommandArgum
Case Me.CommandNames.Delete.ToS
RaiseEvent DeleteClicked(e.CommandArg
End Select
End Sub
'Used for an example dataset (normally obtained externally)
Private ReadOnly Property getADataSet() As DataSet
Get
Page.Trace.Write("getAData
Dim ds As New DataSet
ds.Tables.Add("Table1")
ds.Tables(0).Columns.Add("
ds.Tables(0).Columns.Add("
For i As Integer = 0 To 2
Dim dr As DataRow = ds.Tables(0).NewRow
dr.Item("ArgumentData") = "Item " + i.ToString
dr.Item("AlternateTextData
ds.Tables(0).Rows.Add(dr)
Next
Return ds
End Get
End Property
End Class
Public Class TemplateDataListItems
Implements ITemplate
Public Sub InstantiateIn(ByVal container As System.Web.UI.Control) Implements System.Web.UI.ITemplate.In
Dim ibEdit As New ImageButton
AddHandler ibEdit.DataBinding, AddressOf BindEdit
container.Controls.Add(ibE
Dim ibDelete As New ImageButton
AddHandler ibDelete.DataBinding, AddressOf BindDelete
container.Controls.Add(ibD
End Sub
Private Sub BindEdit(ByVal sender As Object, ByVal e As EventArgs)
Dim l As ImageButton = sender
Dim container As DataListItem = l.NamingContainer()
l.ID = "ibEdit"
l.CommandName = MyCustomControl.CommandNam
l.AlternateText = "Edit (" + container.DataItem("Altern
l.CommandArgument = container.DataItem("Argume
l.ImageUrl = "/noimage.gif"
End Sub
Private Sub BindDelete(ByVal sender As Object, ByVal e As EventArgs)
Dim l As ImageButton = sender
Dim container As DataListItem = l.NamingContainer()
l.ID = "ibDelete"
l.CommandName = MyCustomControl.CommandNam
l.AlternateText = "Delete (" + container.DataItem("Altern
l.CommandArgument = container.DataItem("Argume
l.ImageUrl = "/noimage.gif"
End Sub
End Class
"The only thing that I need to figure out is how to get the Postback / viewstate working properly so that we don't have to load data every time"
Why do you post another question on this, be glad to help...
Why do you post another question on this, be glad to help...
ASKER
I was thinking it was a little out of scope for this thread. I'll post one if I need some help. Again, appreciate the help & learned a lot.
Sure thing, no problem, I always enjoy a good challenge.
Correct me if I'm missing it, or you just forgot to show it in this code example, but I never see where you are adding an event handler to the imagebutton after it has been created in the datalist. For example, I would imagine you would need something like this in your custom control:
Private Sub _MyDataList_ItemCreated(By
If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingIt
Dim ib As ImageButton = DirectCast(e.Item.Controls
AddHandler ib.Command, AddressOf SomeEvent
End If
End Sub
--Michael