First off, the AJAX controls for .NET are fantastic - I am absolutely head-over-heels in love with them. Unfortunately, I'm having a small problem.
I have an UpdatePanel on my page, and it's working very well. I put a datagrid in there, ran asynch' commands to the server to remove data from a database, and the datagrid updates nicely with no post back.
My next step was to build a list of data-objects representing values in a database upon page load. I want this list to exist within my updatePanel, and have linkbuttons that when clicked will make a call back to the server, remove their corresponding record,
and watch as the update panel keeps me up-to-date.
Here's how I have things laid out right now:
Default.aspx:
...
<asp:UpdatePanel id="MyPanel" runat="Server">
<asp:Table id="myTable" runat="Server">
</asp:Table>
</asp:UpdatePanel>
...
Default.aspx.vb:
Protected Sub Page_Init(...)
DrawTicket() ' Draws my list
End Sub
Protected Sub myButton_Click(...)
' This line removes a database record based
' upon the commandArgument of the sender
DrawTicket() ' Draws my list
End Sub
Protected Sub DrawTicket()
Make a New TableRow
Make a New TableCell
Make a new LinkButton
Set The CommandArgument of linkButton
Set The CommandName of linkButton
' This line kills my asynch post-backs, and forces
' Full page post backs
AddHandler LinkButton.Click, AddressOf myButton_Click
myTable.Rows.Add(TableRow)
End Sub
-
-
Add
ScriptManager1.RegisterAsyncPostBackControl(linkButton)
for each link button in the DrawTicket function. That should enable the post backs of the link button to go through the script manager. -
NuTcAsE wrote:Add
ScriptManager1.RegisterAsyncPostBackControl(linkButton)
for each link button in the DrawTicket function. That should enable the post backs of the link button to go through the script manager.
Excellent, that fixed the async aspect of it. But it's still only responding to every-other click...
It's so weird....I have two labels on my page too...one to show the last time the page was accessed, and one to show the last time the UpdatePanel updated....When I click a linkButton, and pass back a value to the server, it removes a record from the database, redraws the list of linkbuttons, and updates the label showing the updatepanel has been updated.
But on every second click, it updates the time, but doesn't actually delete the corresponding record...This lifecycle is odd
-
jsampsonPC wrote:
Excellent, that fixed the async aspect of it. But it's still only responding to every-other click...
It's so weird....I have two labels on my page too...one to show the last time the page was accessed, and one to show the last time the UpdatePanel updated....When I click a linkButton, and pass back a value to the server, it removes a record from the database, redraws the list of linkbuttons, and updates the label showing the updatepanel has been updated.
But on every second click, it updates the time, but doesn't actually delete the corresponding record...This lifecycle is odd
Could it be that when the table containing the list of linkbuttons is updated, after the first click, the command arguments are incorrect?
It's hard to tell what the problem could be but the lifecycle with dynamic controls and UpdatePanel should be the same as dynamic controls in plain ASP.Net. -
Hmm, here's another thing I just noticed:
When my page loads, I click a linkbutton, it responds by deleting the corresponding record from the database, and updating the updatepanel...then It comes to the where it will ignore my next demand..
When I hover over a linkbutton now, it tells me "javascript:__doPostBack('ctl63','')", then I click it, and it doesn't respond, then I hover over it again and now the very same linkbutton says "javascript:__doPostBack('31','')"....I am not sure yet why the value is changing...It's almost as if an incorrect value is being placed on there after a successful command is executed, and then when I try to click a linkbutton with an incorrect value, the page fixes itself, showing me the true value, and then allows me to do a successful postback. -
I think you're right, after a successful command has been ran, it's messing up my commandArguments some how - I'm going to take a moment and look further into this.
-
jsampsonPC wrote:Hmm, here's another thing I just noticed:
When my page loads, I click a linkbutton, it responds by deleting the corresponding record from the database, and updating the updatepanel...then It comes to the where it will ignore my next demand..
When I hover over a linkbutton now, it tells me "javascript:__doPostBack('ctl63','')", then I click it, and it doesn't respond, then I hover over it again and now the very same linkbutton says "javascript:__doPostBack('31','')"....I am not sure yet why the value is changing...It's almost as if an incorrect value is being placed on there after a successful command is executed, and then when I try to click a linkbutton with an incorrect value, the page fixes itself, showing me the true value, and then allows me to do a successful postback.
Do you mind posting your source code? You can strip out the database stuff. I'm guessing that somewhere during that first click its almost as if the click event's postback event reference is being replaced. -
Sure, give me one second to gather it and clean it up a bit for public-viewing. Here's some numbers I recorded after a few click-events:
Page Loads:
LnkBtn 1667 ctl03
LnkBtn 1668 ctl05
LnkBtn 1669 ctl07
LnkBtn 1670 ctl09
Click to delete 1667, successfully deleted:
Page Is PostedBack
LnkBtn 1668 ctl23
LnkBtn 1669 ctl25
LnkBtn 1670 ctl27
Click to delete 1668, failed but UpdatePanel updates:
LnkBtn 1668 ctl03
LnkBtn 1669 ctl05
LnkBtn 1670 ctl07
Click to delete 1668, successfully deleted:
Those are the linkButtons, and their corresponding value in the doPostBack() function call on the client. -
Default.aspx
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>
<!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>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="timeLabel" runat="server"></asp:Label>
<asp:ScriptManager ID="mySM" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="myUP" runat="server">
<ContentTemplate>
<asp:Label ID="myLabel" runat="server"></asp:Label>
<asp:Label ID="tableLabel" runat="server"></asp:Label>
<asp:TextBox ID="webSVtext" runat="server"></asp:TextBox>
<asp:Table ID="userTicket" runat="server"></asp:Table>
<asp:GridView ID="myLittleGrid" runat="server"></asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
<script type="text/javascript">
</script>
</body>
</html>
Default.aspx.vb
Imports System.Web.Configuration.WebConfigurationManager
Partial Class _Default
Inherits System.Web.UI.Page
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
Dim myButton As New LinkButton
myButton.ID = "myButton"
myButton.Text = "Step 2/3 Button"
AddHandler myButton.Click, AddressOf myButton_Click
myUP.ContentTemplateContainer.Controls.Add(myButton)
DrawTicket()
DrawGrid()
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
timeLabel.Text = DateTime.Now.ToString()
myLabel.Text = DateTime.Now.ToString()
End Sub
Protected Sub myButton_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Dim myService As New GetNumberOfProductsInOrder
'webSVtext.Text = myService.RemoveOption(webSVtext.Text).ToString()
webSVtext.Text = myService.RemoveOption(CType(sender, LinkButton).CommandArgument).ToString()
DrawGrid()
DrawTicket()
End Sub
Protected Sub DrawGrid()
Dim myConn As New SqlConnection("...")
Dim myComm As New SqlCommand("sp_DoSomething")
myComm.CommandType = CommandType.StoredProcedure
Dim myAdap As New SqlDataAdapter(myComm)
Dim myDS As New DataTable
myComm.Connection = myConn
Try
myConn.Open()
myAdap.Fill(myDS)
myLittleGrid.DataSource = myDS
myLittleGrid.DataBind()
Catch ex As Exception
Page.Title = ex.Message()
Finally
myConn.Close()
End Try
End Sub
Protected Sub DrawTicket()
userTicket.Rows.Clear()
' Create a database connection
Dim myConn As New SqlConnection("...")
Dim myComm As New SqlCommand("sp_GetStuff")
myComm.CommandType = CommandType.StoredProcedure
myComm.Connection = myConn
Dim myReader As SqlDataReader
Try
myConn.Open()
myReader = myComm.ExecuteReader()
While myReader.Read()
Dim myRow As New TableRow
Dim mycell1 As New TableCell
Dim mycell2 As New TableCell
Dim myButton As New LinkButton
myButton.Text = myReader("StandingOptionID").ToString()
myButton.CommandArgument = myReader("StandingOptionID").ToString()
AddHandler myButton.Click, AddressOf myButton_Click
mySM.RegisterAsyncPostBackControl(myButton)
Dim myLabel As New Label
myLabel.Text = myReader("ProductTitle").ToString()
mycell1.Controls.Add(myButton)
mycell2.Controls.Add(myLabel)
myRow.Cells.Add(mycell1)
myRow.Cells.Add(mycell2)
userTicket.Rows.Add(myRow)
End While
Catch ex As SqlException
tableLabel.Text = ex.Message()
Finally
myConn.Close()
End Try
End Sub
End Class
-
jsampsonPC wrote:
snip..source code
I think I figured out why its not responding on the second click. Heres what happens;
when the page is created for the first time it creates the rows and link buttons and starts assigning them ClientID values based on control sequence, so lest say those link buttons are assigned ctl01, ctl02, ctl03.
When the link button is clicked, the page init starts again and re-creates the linkbutton (DrawTicket()) and assigned them ControlID's ctl01, ctl02, ctl03. Then the click event handler launches removes the ticket and then re-draws the link buttons. Heres where it starts to get screwey... when the link buttons are re-created they are assigned ControlID's ctl04, ctl05 because ctl01, ctl02, ctl03 were previously created (even though the table.Rows.Clear() function is called.)
So now on the second click, the page_init calls DrawTable() and re-creates the linkButtons, but this time they are assigned ctl01, ctl02. But the request param __EVENTTARGET contains 'ctl04' which doesnt exist so the click event is not fired and the page is redrawn... now with the right ID's. -
So to test that I should not find a button with a ctl-value lower than the highest number found on an initial page load. What I mean is, if I load the page, and I have ctl03 - ctl10, and I delete 03, on the postback I should have only controls with an id greater than ctl10?
I'll check to see how these work...
Any suggestions if this is indeed the case? -
I think you're absolutely right...the ctl-numbers never overlap. On the successful load, they are low numbers, starting at about 3, and going to about 11. On the postback, which is the unsuccessful load, they are all high numbers, starting at about 1 over the upper-bound of the previous page-load. It looks just as you suggested.
-
jsampsonPC wrote:So to test that I should not find a button with a ctl-value lower than the highest number found on an initial page load. What I mean is, if I load the page, and I have ctl03 - ctl10, and I delete 03, on the postback I should have only controls with an id greater than ctl10?
I'll check to see how these work...
Any suggestions if this is indeed the case?
Give the link buttons explicit ID values. For example, in each While (reader.Rad()) set the mybutton.ID = "deleteTicketButton" + reader.GetInt32(0).ToString (assuming reader.GetInt32(0) is some unique identifier).
That way the ClientID generated for the link buttons will not follow the dynamic control ID assignment that ASP.Net does for dynamic controls.
[Edit: Spelling and grammer... some days...grrr] -
NuTcAsE wrote:

jsampsonPC wrote:
So to test that I should not find a button with a ctl-value lower than the highest number found on an initial page load. What I mean is, if I load the page, and I have ctl03 - ctl10, and I delete 03, on the postback I should have only controls with an id greater than ctl10?
I'll check to see how these work...
Any suggestions if this is indeed the case?
Give the link buttons explicit ID values. For example, in each While (reader.Rad()) set the mybutton.ID = "deleteTicketButton" + reader.GetInt32(0).ToString (assuming reader.GetInt32(0) is some unique identifier).
That way the ClientID generated for the link buttons will not follow the dynamic control ID assignment that ASP.Net does for dynamic controls.
[Edit: Spelling and grammer... some days...grrr]
Also another suggestion. Dont use the Click event of the LinkButtons, instead register a event handler for Command. In the Click event hander you will always have to type cast the sender to the LinkButton to get the CommandArgument value, while in the Command event handler its there in the event args. -
NuTcAsE wrote:...Give the link buttons explicit ID values...
That works! Dang, I wish the solution would have been more complex
Thanks, NutCase.
-
jsampsonPC wrote:

NuTcAsE wrote:
...Give the link buttons explicit ID values...
That works! Dang, I wish the solution would have been more complex
Thanks, NutCase.
Awesome!
Thread Closed
This thread is kinda stale and has been closed but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.