asp.netwebformsupdatepaneldopostback

Click on panel causes asynchronous postback but click on children causes full page postback


I have the following ASCX control:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="CalendarDay.ascx.cs" 
    Inherits="MVP.Calendar.CalendarDay" %>

<asp:Panel ID="DayWrapper" runat="server" 
    CssClass="day col p-2 border border-left-0 border-top-0 text-truncate">
    <div class="date d-flex align-items-center justify-content-center <%= CurrentDayTag %>">
        <%= DayText %>
    </div>
    <div class="row pl-3 pr-3 d-none d-sm-block">
        <p class="info"><%= InfoText %></p>
        <a class="d-block rounded small align-self-start" title="Test 1"><%= PriceText %></a>
    </div>
</asp:Panel>

Here's part of its code-behind:

public partial class CalendarDay : UserControl, IPostBackEventHandler
{
    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);

        DayWrapper.CssClass += DayBackgroundTag;
        DayWrapper.Attributes["onclick"] = "javascript:__doPostBack('" + UniqueID + "', '')";
    }

    void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)
    {
        OnDayClicked();
    }
}

Here's the DOM that's rendered:

<div id="MainContent_CalDate_WeekRepeater_DayRepeater_3_CalendarDay_1_DayWrapper_1"
    class="day col p-2 border border-left-0 border-top-0 text-truncate day--fully-available"
    onclick="javascript:__doPostBack('ctl00$MainContent$CalDate$WeekRepeater$ctl03$DayRepeater$ctl01$CalendarDay', '')">
    <div class="date d-flex align-items-center justify-content-center ">17</div>
    <div class="row pl-3 pr-3 d-none d-sm-block">
        <p class="info"></p>
        <a class="d-block rounded small align-self-start" title="Test 1">10€</a>
    </div>
</div>

This ASCX control is inside a rather complex hierarchy, but ultimately, all of this is inside an UpdatePanel.

On that rendered HTML, if I click on the 17 or on the 10€ text, I get a full page postback, but if I click anywhere else within the top div, I get an AJAX call from my UpdatePanel. Both these calls are triggering the RaisePostBackEvent function correctly.

I want and would expect to get the AJAX call every time.

Why is this happening, and how can I fix it?


Solution

  • You may need to register the control for async postback. Try changing this;

    DayWrapper.Attributes["onclick"] = "javascript:__doPostBack('" + UniqueID + "', '')";
    

    To this:

    DayWrapper.Attributes["onclick"] = Page.ClientScript.GetPostBackEventReference(new PostBackOptions(this));
    ScriptManager.GetCurrent(Page).RegisterAsyncPostBackControl(this);
    

    The main difference here the call to RegisterAsyncPostBackControl which tells the ScriptManager that the control should indeed be used for async postback. I am also changing the way that the postback link is generated. This might not actually be necessary, but it seems cleaner than manually generating the JavaScript.