I have an ASP.NET web page with two postback events and the second one is aborting the first. The second one then doesn't render as expected once it completes.
In Detail
I have an ASP.NET web page that effectively contains two link buttons. It uses the Telerik ASP.NET AJAX controls, but I'm not sure if the behaviour is specfic to these controls:
The Page - an extremely cut-down version is as follows:
<telerik:RadToolTipManager ID="RadToolTipManager1" runat="server"
Position="BottomLeft" RelativeTo="Element" ShowEvent="OnClick"
HideEvent="ManualClose" Animation="Fade" OnAjaxUpdate="OnShowItems" >
<TargetControls>
<telerik:ToolTipTargetControl TargetControlID="btnShowItems" />
</TargetControls>
</telerik:RadToolTipManager>
...
...
<asp:LinkButton ID="btnShowItems" runat="server" Visible="false">
<span><%= ItemsPrompt %></span>
</asp:LinkButton>
...
...
<uc1:X ID="XControl" runat="server"/>
The UserControl "X" - an extremely cut-down version is as follows:
<telerik:RadAjaxPanel ID="RadAjaxPanel1" runat="server"
LoadingPanelID="LoadingPanel1" RenderMode="Block">
<asp:LinkButton runat="server" ID="CausePostbackButton"
Style="display: none" />
</telerik:RadAjaxPanel>
Use Case #1 - successful
Use Case #2 - failure
The page loads and a JavaScript timer within Control "X" activates a postback on the LinkButton "CausePostbackButton". (So, this mimics a user clicking the button).
Before the server has time to respond, the User clicks on the LinkButton "btnShowItems".
In FireFox/Firebug, you can see that the first post-back event is "Aborted". The second post-back event completes (you can see the time taken reported) but the page is not visually updated.
If the "manual" button is then clicked again, then that works as expected.
My thoughts
I know that JavaScript is single threaded, so if events can't be run immediately then they are queued.
I know that if a timer fires an event that is queued and then fires the same event whilst the first event is still queued, then one of these events (the second?) will be dropped.
This is acting as if the first event is being trashed, but then the second event can no longer find its "channel" to write to.
However, if I change the "manual" Link Button to an Image Button then the behaviour does not change.
Any ideas what the problem is (and ideally a solution)?
Many thanks in advance
Griff
submitted by bmcmillen<%@ Page Language="C#" AutoEventWireup="true" %> <%@ Import Namespace="System.Data" %> <!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>How to Change the TotalRowCount ...</title> </head> <body> <form id="form1" runat="server"> <script runat="server" language="c#"> protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { this.RadGrid1.DataSource = DataPage(0); this.RadGrid1.DataBind(); } } public DataRow[] DataPage(int PageIndex) { string sql = string.Empty; switch (this.RadComboBox1.SelectedValue) { case "2": sql = "pkID >= " + (PageIndex * 5 + 1) + " AND pkID <= " + (PageIndex * 5 + 5) + ""; return dt2().Select(sql); default: sql = "pkID >= " + (PageIndex * 5 + 1) + " AND pkID <= " + (PageIndex * 5 + 5) + ""; return dt1().Select(sql); } } protected void RadComboBox1_SelectedIndexChanged(object sender, Telerik.Web.UI.RadComboBoxSelectedIndexChangedEventArgs e) { this.RadGrid1.DataSource = DataPage(this.RadDataPager1.CurrentPageIndex); this.RadGrid1.DataBind(); } protected void RadDataPager1_PageIndexChanged(object sender, RadDataPagerPageIndexChangeEventArgs e) { this.RadGrid1.DataSource = DataPage(e.NewPageIndex); this.RadGrid1.DataBind(); } protected void RadDataPager1_TotalRowCountRequest(object sender, RadDataPagerTotalRowCountRequestEventArgs e) { this.RadDataPager1.TabIndex = 1; switch (this.RadComboBox1.SelectedValue) { case "1": e.TotalRowCount = dt1().Rows.Count; break; case "2": e.TotalRowCount = dt2().Rows.Count; break; } } public static DataTable dt1() { DataTable table = new DataTable(); table.Columns.Add("pkID", typeof(Int32)); table.Columns.Add("ParentID", typeof(Int32)); table.Columns.Add("Name", typeof(String)); table.Columns.Add("Text", typeof(String)); table.Rows.Add(new object[] { 1, 1, "testName1", "testText1" }); table.Rows.Add(new object[] { 2, 1, "testName2", "testText2" }); table.Rows.Add(new object[] { 3, 1, "testName3", "testText3" }); table.Rows.Add(new object[] { 4, 1, "testName4", "testText4" }); table.Rows.Add(new object[] { 5, 1, "testName5", "testText5" }); table.Rows.Add(new object[] { 6, 1, "testName6", "testText6" }); table.Rows.Add(new object[] { 7, 1, "testName7", "testText7" }); table.Rows.Add(new object[] { 8, 1, "testName8", "testText8" }); table.Rows.Add(new object[] { 9, 1, "testName9", "testText9" }); table.Rows.Add(new object[] { 10, 1, "testName10", "testText10" }); table.Rows.Add(new object[] { 11, 1, "testName11", "testText11" }); table.Rows.Add(new object[] { 12, 1, "testName12", "testText12" }); return table; } public static DataTable dt2() { DataTable table = new DataTable(); table.Columns.Add("pkID", typeof(Int32)); table.Columns.Add("Name", typeof(String)); table.Rows.Add(new object[] { 1, "C" }); table.Rows.Add(new object[] { 2, "C++" }); table.Rows.Add(new object[] { 3, "C#" }); table.Rows.Add(new object[] { 4, "Java" }); table.Rows.Add(new object[] { 5, "F++" }); table.Rows.Add(new object[] { 6, "Z++" }); return table; } </script> <telerik:RadScriptManager ID="RadScriptManager1" runat="server" /> <telerik:RadAjaxManager ID="RadAjaxManager1" runat="server"> <AjaxSettings> <telerik:AjaxSetting AjaxControlID="RadComboBox1"> <UpdatedControls> <telerik:AjaxUpdatedControl ControlID="RadComboBox1" /> <telerik:AjaxUpdatedControl ControlID="RadGrid1" /> <telerik:AjaxUpdatedControl ControlID="RadDataPager1" /> </UpdatedControls> </telerik:AjaxSetting> <telerik:AjaxSetting AjaxControlID="RadDataPager1"> <UpdatedControls> <telerik:AjaxUpdatedControl ControlID="RadDataPager1" /> <telerik:AjaxUpdatedControl ControlID="RadGrid1" /> </UpdatedControls> </telerik:AjaxSetting> </AjaxSettings> </telerik:RadAjaxManager> <telerik:RadComboBox ID="RadComboBox1" Runat="server" AutoPostBack="true" onselectedindexchanged="RadComboBox1_SelectedIndexChanged"> <Items> <telerik:RadComboBoxItem runat="server" Text="RadComboBoxItem1" Value="1" Selected="true" /> <telerik:RadComboBoxItem runat="server" Text="RadComboBoxItem2" Value="2" /> </Items> </telerik:RadComboBox> <telerik:RadGrid ID="RadGrid1" runat="server" PageSize="5"> </telerik:RadGrid> <telerik:RadDataPager ID="RadDataPager1" runat="server" PageSize="5" ontotalrowcountrequest="RadDataPager1_TotalRowCountRequest" onpageindexchanged="RadDataPager1_PageIndexChanged"> <Fields> <telerik:RadDataPagerButtonField FieldType="NextLast" HorizontalPosition="RightFloat" /> <telerik:RadDataPagerButtonField FieldType="Numeric" PageButtonCount="10" HorizontalPosition="RightFloat" /> <telerik:RadDataPagerButtonField FieldType="FirstPrev" HorizontalPosition="RightFloat" /> <telerik:RadDataPagerGoToPageField CurrentPageText="" TotalPageText="/" TextBoxWidth="38" SubmitButtonText="Go" HorizontalPosition="RightFloat" /> </Fields> </telerik:RadDataPager> </form> </body> </html>
public class Property2Template : ITemplate { public void InstantiateIn(Control container) { Label label1 = new Label(); RadTreeNode node = (RadTreeNode)container; label1.Text = "Property 2: <span class=\"PropertyValue\">" + node.Text + "</span>"; label1.CssClass = "PropertyLabel"; container.Controls.Add(label1); } }public class Property2Template : ITemplate { public void InstantiateIn(Control container) { Label label1 = new Label(); Label label2 = new Label(); RadTreeNode node = (RadTreeNode)container; label1.Text = "Property 2: "; label1.CssClass = "PropertyLabel"; label2.Text = node.Text; label2.CssClass = "PropertyValue"; label2.DataBinding += new EventHandler(label2_DataBinding); container.Controls.Add(label1); container.Controls.Add(label2); } public void label2_DataBinding(object sender, EventArgs e) { Label target = (Label)sender; RadTreeNode node = (RadTreeNode)target.BindingContainer; string nodeText = (string)DataBinder.Eval(node, "Text"); target.Text = nodeText; } }
