This one is REALLY driving me nuts. I've read, and tried, most of the workarounds but still it posts back!!
All the markup is generated dynamically from code-behind and inserted into a page that is part of a Master Page, from the init event.
There are a series of nested tabs, the tab content for the most part is data in a GridView. Each Gridview is set in it's own update panel. Every time a LinkButton in the GridView is clicked there is a full postback causing the tabs to reset (any button outside of the GridView and in the UpdatePanel doesn't cause a full postback.
LinkButtons are generated like this
Dim Select_Field As New CommandField
With Select_Field
.HeaderText = "View Transactions"
.SelectText = "View Transactions"
.ShowSelectButton = True
End With
GV.Columns.Add(Select_Field)
Registering with ToolKitScriptManager
Private Sub AssessmentsMain_RowDataBound(sender As Object, e As GridViewRowEventArgs)
Try
If e.Row.RowType = DataControlRowType.DataRow Then
Dim vID As Integer = Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, "ID"))
Dim LB As LinkButton = CType(e.Row.Cells(4).Controls(0), LinkButton)
LB.ID = "AssMain_" & vID
AjaxControlToolkit.ToolkitScriptManager.GetCurrent(Me).RegisterAsyncPostBackControl(LB)
End If
Catch ex As Exception
Dim vError As New SendError
vError.MailError("840", PageName, ex)
ShowError()
End Try
End Sub
and the generated markup for one row is like this
<tr class="GridView" style="color:#333333;background-color:#F7F6F3;">
<td>10</td>
<td>Adam White</td>
<td>4224 Res Road</td>
<td align="right">$6,850.65</td>
<td>
<a id="ctl00_ContentPlaceHolder1_AssessmentsMainGV_ctl02_AssMain_10" href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$AssessmentsMainGV','Select$0')" style="color:#333333;">View Transactions</a>
The GridView class
Public Class HAS_Gridview
Inherits GridView
Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
MyBase.OnInit(e)
CellPadding = 4
GridLines = WebControls.GridLines.None
ForeColor = Drawing.ColorTranslator.FromHtml("#333333")
ClientIDMode = UI.ClientIDMode.AutoID
With MyBase.FooterStyle
.BackColor = Drawing.ColorTranslator.FromHtml("#E2DED6")
.Font.Bold = True
.ForeColor = Color.White
End With
RowStyle.BackColor = Drawing.ColorTranslator.FromHtml("#F7F6F3")
RowStyle.ForeColor = Drawing.ColorTranslator.FromHtml("#333333")
PagerStyle.HorizontalAlign = WebControls.HorizontalAlign.Center
PagerStyle.ForeColor = Color.Black
PagerStyle.BackColor = Drawing.ColorTranslator.FromHtml("#E2DED6")
With MyBase.SelectedRowStyle
.BackColor = Drawing.ColorTranslator.FromHtml("#E2DED6")
.Font.Bold = True
.ForeColor = Drawing.ColorTranslator.FromHtml("#333333")
End With
With MyBase.HeaderStyle
.BackColor = Drawing.ColorTranslator.FromHtml("#E2DED6")
.Font.Bold = True
.ForeColor = Color.Black
.CssClass = "GridView"
End With
EditRowStyle.BackColor = Drawing.ColorTranslator.FromHtml("#999999")
With MyBase.AlternatingRowStyle
.BackColor = Color.White
.ForeColor = Drawing.ColorTranslator.FromHtml("#284775")
.CssClass = "GridView"
End With
With MyBase.RowStyle
.CssClass = "GridView"
End With
End Sub
End Class
In the end the only way I could get this to work was
Create a class for a LinkButton Template
Public Class LinkButtonTemplate
Implements ITemplate
Private m_ColumnName As String
Event LinkButtonItem_Clicked(sender As LinkButton, e As EventArgs)
Public Property ColumnName() As String
Get
Return m_ColumnName
End Get
Set(ByVal value As String)
m_ColumnName = value
End Set
End Property
Public Sub New()
End Sub
Public Sub New(ByVal ColumnName As String)
Me.ColumnName = ColumnName
End Sub
Public Sub InstantiateIn(container As Control) Implements ITemplate.InstantiateIn
Dim LB As New LinkButton()
With LB
.ID = "LB_" & ColumnName
.Text = ColumnName
.OnClientClick = "LinkButtonClick(this);"
End With
container.Controls.Add(LB)
End Sub
End Class
Add this javascript so that it would post the ID to a hidden field and click a hidden button
Private Sub LoadLinkButtonClick()
Try
Dim SB As New StringBuilder
SB.Append("function LinkButtonClick(LinkButton){ ")
SB.Append("setTimeout(function() { ")
SB.Append("$get('" & GridViewLBClicked.ClientID & "').click(); ")
SB.Append(" }, 300); ")
SB.Append("var sendingID = LinkButton.id; ")
SB.Append("document.getElementById('" & HiddenField1.ClientID & "').value = sendingID; ")
SB.Append("} ")
ScriptManager.RegisterStartupScript(Me, Me.GetType(), "LoadLinkButton", SB.ToString, True)
Catch ex As Exception
Dim vError As New SendError
vError.MailError("1229", PageName, ex)
End Try
End Sub
On the RowDataBound event capture the ID we need and add it to the LinkButton ID (so now we know both the sending GridView and the selected row)
Private Sub AssessmentsMain_RowDataBound(sender As Object, e As GridViewRowEventArgs)
Try
If e.Row.RowType = DataControlRowType.DataRow Then
Dim vID As Integer = Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, "ID"))
Dim LB As LinkButton = CType(e.Row.Cells(4).Controls(0), LinkButton)
LB.ID = "AssMain_" & vID
End If
Catch ex As Exception
Dim vError As New SendError
vError.MailError("840", PageName, ex)
ShowError()
End Try
End Sub
From the hidden button click we can recover all the data we need to make the async postback
Private Sub RaiseLinkButton_Click(sender As Object, e As EventArgs)
Try
Dim vFunction As New Functions
Dim vValue As String = HiddenField1.Value
Dim vSplit = vValue.Split("_")
Dim i As Integer = 0
For Count As Integer = 0 To vSplit.Length - 1
i += 1
Next
Dim DGName As String = vSplit(i - 2)
Select Case DGName
Case "AssMain"
Dim MV As MultiView = vFunction.FindControlRecursive(BodyMain, "AssessmentMultiView")
Dim GV As CustomControl.HAS_Gridview = vFunction.FindControlRecursive(BodyMain, "AssessmentDetailGV")
With GV
.DataSource = AssessmentsDetail_ReturnDataSet()
.DataBind()
.PageIndex = 0
End With
MV.ActiveViewIndex = 1
Dim vPanel As UpdatePanel = vFunction.FindControlRecursive(BodyMain, "AssessmentUpdatePanel")
vPanel.Update()
End Select
Catch ex As Exception
Dim vError As New SendError
vError.MailError("953", PageName, ex)
ShowError()
End Try
End Sub