I went back to researching how to wire up dynamically created links/buttons in a template to click (command) events because I was never able to get this to work in the past.
The first thing to note is that you Must create your columns in your Page Init Event.
If you do not do this, the events for the controls created dynamically in your template will be lost. They will post back to the server, but then the event cease to exist.
Another thing to note is that events are handled by the controls that they occur in. This means that you have to implement code that handles the event in your ITemplate class. If you want this to be handled in the Page that the template belongs to you will have to Bubble Up the event.
One last thing to note is that Click Events
do not automatically bubble up for LinkButtons, Buttons and ImageButtons. Only the Command Event will bubble up.
The following is an example of some code that creates a template and bubbles up the Command Event of the link buttons in the template to the Page that the template belongs to:
- Public Partial Class Practice
-
Inherits System.Web.UI.Page
-
Private _theSource As List(Of SomeClass)
-
-
Private Sub Practice_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
-
_theSource = New List(Of SomeClass)
-
_theSource.Add(New SomeClass("first", "data 1"))
-
_theSource.Add(New SomeClass("second", "data 2"))
-
_theSource.Add(New SomeClass("third", "data 3"))
-
_theSource.Add(New SomeClass("fourth", "data 4"))
-
Session("_theSource") = _theSource
-
-
'Please note that we are creating the GridView's Columns in the Page Init event.
-
'This is important because if you do not create the columns at this stage in the
-
'page life cycle the event for the dynamic link buttons will be lost!
-
-
Dim tf As New TemplateField
-
tf.HeaderText = "My Stuff"
-
-
'My Template is a Private Class that implements the ITemplate Field
-
'See it's definition farther down in the code.
-
Dim item As New MyTemplate()
-
-
'Assigning the function named "MyCommandHandlingFunction" to handle the templates LinkButtonCommand Event
-
AddHandler item.LinkButtonCommand, New CommandEventHandler(AddressOf MyCommandHandlingFunction)
-
-
'I was using the following in an attempt to bubble up the Click event for the
-
'Dynamic Link Button but this will never happen because I discovered that
-
'Only the Command Event will bubble up.
-
' AddHandler item.LinkButtonClick, New EventHandler(AddressOf MyCommandHandlingFunction)
-
-
-
'Adding the item to the template field
-
tf.ItemTemplate = item
-
-
'Creating the GridView's columns
-
myGrid.Columns.Add(tf)
-
-
End Sub
-
-
'This method simply binds the data source to the data grid
-
Private Sub DisplayGridView()
-
If _theSource Is Nothing Then
-
_theSource = Session("_theSource")
-
End If
-
myGrid.DataSource = _theSource
-
myGrid.DataBind()
-
End Sub
-
-
Private Sub Practice_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender
-
DisplayGridView()
-
End Sub
-
-
'This method handles the Command Event that originates from the LinkButton
-
'In the Template
-
Private Sub MyCommandHandlingFunction(ByVal sender As Object, ByVal e As CommandEventArgs)
-
'e.CommandArgument contains "Sort"...we set this in the Template
-
End Sub
-
-
' Private Sub MyClickHandlingFunction(ByVal sender As Object, ByVal e As EventArgs)
-
'
-
' End Sub
-
-
-
Private Class MyTemplate
-
Implements ITemplate
-
'Expose the command event handler - when the command event handler is trapped internally this event is raised to inform the container
-
Public Event LinkButtonCommand As CommandEventHandler
-
'Public Event LinkButtonClick As EventHandler
-
-
Public Sub InstantiateIn(ByVal container As System.Web.UI.Control) Implements System.Web.UI.ITemplate.InstantiateIn
-
Dim text As New Label
-
text.Style.Add("display", "block")
-
text.Style.Add("width", "80px")
-
text.Style.Add("float", "left")
-
-
AddHandler text.DataBinding, AddressOf Me.BindText
-
container.Controls.Add(text)
-
-
Dim lnkBtn As New LinkButton
-
lnkBtn.Style.Add("float", "left")
-
AddHandler lnkBtn.DataBinding, AddressOf Me.BindLinkButtons
-
'AddHandler lnkBtn.Click, New EventHandler(AddressOf Click)
-
AddHandler lnkBtn.Command, New CommandEventHandler(AddressOf Command)
-
container.Controls.Add(lnkBtn)
-
End Sub
-
-
Private Sub BindLinkButtons(ByVal sender As Object, ByVal e As EventArgs)
-
Dim lnkBtn As LinkButton = CType(sender, LinkButton)
-
Dim container As GridViewRow = CType(lnkBtn.NamingContainer, GridViewRow)
-
Dim cellContent As String = DataBinder.Eval(container.DataItem, "Content").ToString
-
lnkBtn.Text = cellContent
-
lnkBtn.CommandArgument = "Sort"
-
-
End Sub
-
Private Sub BindText(ByVal sender As Object, ByVal e As EventArgs)
-
Dim txt As Label = CType(sender, Label)
-
Dim row As GridViewRow = CType(txt.NamingContainer, GridViewRow)
-
Dim cellContent As String = DataBinder.Eval(row.DataItem, "Title").ToString
-
txt.Text = cellContent + ": "
-
End Sub
-
-
''This will crash because the only event that's bubbled up is the Command Event....which takes a parameter of CommandEventArgs
-
'Private Sub Click(ByVal sender As Object, ByVal e As EventArgs)
-
' RaiseEvent LinkButtonClick(Me, e)
-
'End Sub
-
-
'Handles the Command Event:
-
'When the link button is clicked the Command event is bubbled up to the container, which happens to be this class.
-
'This method bubbles the event up to the next level so that the event can be
-
'handled in the Page.
-
Private Sub Command(ByVal sender As Object, ByVal e As CommandEventArgs)
-
RaiseEvent LinkButtonCommand(Me, e)
-
End Sub
-
End Class
-
-
-
-
'This class is used for the DataSource of the GridView
-
Private Class SomeClass
-
Private _title As String
-
Private _content As String
-
Public Property Title() As String
-
Get
-
Return _title
-
End Get
-
Set(ByVal value As String)
-
_title = value
-
End Set
-
End Property
-
Public Property Content() As String
-
Get
-
Return _content
-
End Get
-
Set(ByVal value As String)
-
_content = value
-
End Set
-
End Property
-
-
Public Sub New(ByVal theTitle As String, ByVal theContent As String)
-
_title = theTitle
-
_content = theContent
-
End Sub
-
End Class
-
-
-
End Class
The ASPX code for this page is:
- <%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Practice.aspx.vb" Inherits="ScratchPad.Practice" %>
-
-
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
-
<html xmlns="http://www.w3.org/1999/xhtml" >
-
<head runat="server">
-
<title></title>
-
</head>
-
<body>
-
<form id="form1" runat="server">
-
<div>
-
<asp:GridView ID="myGrid" runat="server"
-
BorderColor="black"
-
GridLines="Horizontal"
-
BorderStyle="None"
-
allowpaging="True"
-
autogeneratecolumns="False"
-
style="margin-left:auto; margin-right:auto;"
-
width="200" EnableViewState="true"></asp:GridView>
-
</div>
-
</form>
-
</body>
-
</html>