Looks like I'm not the only one to come across this. Found a post 9 months
old that deals with the same thing. Here's the fix:

Add line:
b.Text = al(0)
b.ID = "0" '<--------* this line
AddHandler b.Command, AddressOf b_Click


Change the line:
Me.ASPTable.Rows.Clear()
to
Me.RemoveControls(Me.ASPTable)


Add the method:
Private Sub RemoveControls(ByRef container As Control)
'************************************************* ******************
'SUB RemoveControls - parameter Control
'Remove all existing controls from the specified control.
'Start from the end of the control collection
'to avoid index out of range errors
'cannot do this with a for each loop, becuase that would modify
'the collection that the enumerator is bound to, which is an error.
'
' This Method was taken from the following post:
'
[url]http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&selm=yKXbcgHdCHA.2320%40cpmsftngxa06&rnum=6[/url]
'
'************************************************* ******************
Dim ctl As Control
Dim x As Integer
For x = container.Controls.Count - 1 To 0 Step -1
ctl = container.Controls(x)
If ctl.HasControls Then
'do a recursive remove, we are removing the controls in the
container
'before removing the container
RemoveControls(ctl)
End If
container.Controls.Remove(ctl)
Next
End Sub

For those reading this far, I definately had to add an ID to the control for
it to be removed properly. In the future it may also be better to truely
convert this into a custom/server control as stated in the linked post above
since that would be a little cleaner. Also I'm not sure about the
performance using a recursive loop on a large table... we shall see.


"Rick Glos" <rickglos@mbsimsdn.com> wrote in message
news:u$So3pKRDHA.3192@tk2msftngp13.phx.gbl...
> Hello all,
>
> I have a problem with a table I create dynamically. It seems like the
> linkbuttons i add events to don't get wired properly. For testing I
created
> an example page with a simple table of 2x2. I populate each cell with a
> letter of the alphabet that you can click and it will tell you which
letter
> you clicked. I create 2 simple arraylists to represent data, A,B,C,D and
> W,X,Y,Z. I also have a link button on the page which doesn't affect the
> table to represent something else the user might do. I'm trying to keep
the
> 'viewstate' of the table loaded and all the linkbuttons firing correctly.
>
> The code will be below. Here's the steps to recreate. Once you've
started
> the project, click any of the letters, A,B,C,D and you'll get the correct
> response in the 'ASPTableResponse' label. Now click the 'get Z alphabet'
> and the new data loads. Now click 'W' for example and you DO NOT get any
> response to 'ASPTableResponse' label unless you click it a second time.
>
> Can someone explain why and help me understand what I need to do to fix
> this?
>
> Thanks,
> Rick
>
> Web form html:
>
> <%@ Page Language="vb" AutoEventWireup="false"
Codebehind="WebForm1.aspx.vb"
> Inherits="DynamicLinkButtons.WebForm1"%>
> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
> <HTML>
> <HEAD>
> <title>WebForm1</title>
> <meta name="GENERATOR" content="Microsoft Visual Studio.NET 7.0">
> <meta name="CODE_LANGUAGE" content="Visual Basic 7.0">
> <meta name=vs_defaultClientScript content="JavaScript">
> <meta name=vs_targetSchema
> content="http://schemas.microsoft.com/intellisense/ie5">
> </HEAD>
> <body MS_POSITIONING="GridLayout">
>
> <form id="Form1" method="post" runat="server">
>
> <asp:LinkButton ID="HelloWorld" Runat="server">Hello
> World</asp:LinkButton>
> &nbsp;
> <asp:Label ID="HelloWorldResponse" Runat="server"></asp:Label>
>
> <br >
> <br >
>
> <asp:Table
> GridLines="Both"
> ID="ASPTable"
> Runat="server"
> >
> </asp:Table>
> <br />
> <asp:Label ID="ASPTableResponse" Runat="server"></asp:Label>
>
> <br />
> <br />
>
> <asp:LinkButton ID="GetZ" Runat="server">Get Z
alphabet</asp:LinkButton>
> &nbsp;
> <asp:LinkButton ID="GetA" Runat="server">Get A
alphabet</asp:LinkButton>
>
> </form>
>
> </body>
> </HTML>
>
>
> Code behind page:
>
> Public Class WebForm1
> Inherits System.Web.UI.Page
> Protected WithEvents HelloWorld As System.Web.UI.WebControls.LinkButton
> Protected WithEvents HelloWorldResponse As
System.Web.UI.WebControls.Label
> Protected WithEvents ASPTableResponse As System.Web.UI.WebControls.Label
> Protected WithEvents GetZ As System.Web.UI.WebControls.LinkButton
> Protected WithEvents GetA As System.Web.UI.WebControls.LinkButton
> Protected WithEvents ASPTable As System.Web.UI.WebControls.Table
>
> #Region " Web Form Designer Generated Code "
>
> 'This call is required by the Web Form Designer.
> <System.Diagnostics.DebuggerStepThrough()> Private Sub
> InitializeComponent()
>
> End Sub
>
> Private Sub Page_Init(ByVal sender As System.Object, ByVal e As
> System.EventArgs) Handles MyBase.Init
> 'CODEGEN: This method call is required by the Web Form Designer
> 'Do not modify it using the code editor.
> InitializeComponent()
> End Sub
>
> #End Region
>
> Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
> System.EventArgs) Handles MyBase.Load
> 'Put user code to initialize the page here
>
> If Not Page.IsPostBack Then
> ' First time in
>
> ' Get the data from the database and place it in the dynamic table
> ' we don't want to go to the database everytime there's a postback
> GoGetDataFromDataSource("A")
> End If
>
> ' Bind the table to the page
> BuildASPTable()
>
> End Sub
>
>
>
> Private Sub GoGetDataFromDataSource(ByVal AlphaToggle As String)
> ' Pretend you go get some data from a datasource SQL, OLAP, etc...
> ' ...
>
> Response.Write("<br />Inserting arraylist into cache")
>
> Dim al As New ArrayList()
>
> Select Case AlphaToggle
> Case "A"
> al.Add("A")
> al.Add("B")
> al.Add("C")
> al.Add("D")
> Case "Z"
> al.Add("W")
> al.Add("X")
> al.Add("Y")
> al.Add("Z")
> End Select
>
> ' Place it in the cache for 20 minutes
> Cache.Insert("username_cs", al, Nothing, DateTime.Now.AddMinutes(20),
> Cache.NoSlidingExpiration)
>
> End Sub
>
> Private Sub BuildASPTable()
> ' Now use that data to create the table with linkbuttons
> ' pretend there's some fantastic looping in here...
>
> ' Get the data from the cache
> Dim strCacheKey As String = "username_cs"
> If (Cache(strCacheKey) Is Nothing) Then
> ' generate the data if the cache is empty
> Me.GoGetDataFromDataSource("A")
> End If
> Dim al As ArrayList
> al = CType(Cache(strCacheKey), ArrayList)
>
> Dim r As TableRow
> Dim c As TableCell
> Dim b As LinkButton
> r = New TableRow()
> c = New TableCell()
> b = New LinkButton()
> b.Text = al(0)
> AddHandler b.Command, AddressOf b_Click
> c.Controls.Add(b)
> r.Cells.Add(c)
> c = New TableCell()
> b = New LinkButton()
> b.Text = al(1)
> AddHandler b.Command, AddressOf b_Click
> c.Controls.Add(b)
> r.Cells.Add(c)
> ASPTable.Rows.Add(r)
> r = New TableRow()
> c = New TableCell()
> b = New LinkButton()
> b.Text = al(2)
> AddHandler b.Command, AddressOf b_Click
> c.Controls.Add(b)
> r.Cells.Add(c)
> c = New TableCell()
> b = New LinkButton()
> b.Text = al(3)
> AddHandler b.Command, AddressOf b_Click
> c.Controls.Add(b)
> r.Cells.Add(c)
> ASPTable.Rows.Add(r)
> End Sub
>
> Private Sub b_Click(ByVal sender As Object, ByVal e As CommandEventArgs)
> Dim lb As LinkButton = CType(sender, LinkButton)
> ASPTableResponse.Text = "You clicked " & lb.Text & "!"
> End Sub
>
> Private Sub HelloWorld_Click(ByVal sender As Object, ByVal e As
> System.EventArgs) Handles HelloWorld.Click
> HelloWorldResponse.Text = "You clicked Hello World!"
> End Sub
>
> Private Sub GetZ_Click(ByVal sender As Object, ByVal e As
> System.EventArgs) Handles GetZ.Click
> Me.GoGetDataFromDataSource("Z")
> Me.ASPTable.Rows.Clear()
> Me.BuildASPTable()
> End Sub
>
> Private Sub GetA_Click(ByVal sender As Object, ByVal e As
> System.EventArgs) Handles GetA.Click
> Me.GoGetDataFromDataSource("A")
> Me.ASPTable.Rows.Clear()
> Me.BuildASPTable()
> End Sub
>
> End Class
>
>