38

I have a GridView inside of a UpdatePanel. In a template field is a button I use for marking items. Functionally, this works fine, but the button always triggers a full page postback instead of a partial postback. How do I get the button to trigger a partial postback?

<asp:ScriptManager ID="ContentScriptManager" runat="server" />
<asp:UpdatePanel ID="ContentUpdatePanel" runat="server" ChildrenAsTriggers="true">
    <ContentTemplate>
        <asp:GridView ID="OrderGrid" runat="server" AllowPaging="false" AllowSorting="false"
            AutoGenerateColumns="false">
            <Columns>
                <asp:TemplateField HeaderText="">
                    <ItemTemplate>
                        <asp:LinkButton ID="MarkAsCompleteButton" runat="server" Text="MarkAsComplete"
                            CommandName="MarkAsComplete" CommandArgument='<%# Eval("Id") %>' />
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:BoundField DataField="Name" HeaderText="Name" />
                <asp:BoundField DataField="LoadDate" HeaderText="Load Date" />
                <asp:BoundField DataField="EmployeeCutOffDate" HeaderText="Cut Off Date" />
                <asp:BoundField DataField="IsComplete" HeaderText="Is Completed" />
            </Columns>
        </asp:GridView>
    </ContentTemplate>
</asp:UpdatePanel>
NakedBrunch
  • 48,713
  • 13
  • 73
  • 98
Kevin Albrecht
  • 6,974
  • 7
  • 44
  • 56
  • I created this scenario on a fresh project. I could not make your full postback happen, it was a partial every time. Are there any other factors that you can think of that are weird in your case? – Paul Lemke Feb 04 '11 at 16:22
  • Can you post the code of what you are doing on that "MarkAsComplete" command? – Paul Lemke Feb 04 '11 at 16:24
  • Make sure you didn't disable all javascript by using web developer tools on Firefox. – Cem Feb 07 '11 at 14:44

8 Answers8

84

You need to register each and every LinkButton as an AsyncPostBackTrigger. After each row is bound in your GridView, you'll need to search for the LinkButton and register it through code-behind as follows:

protected void OrderGrid_RowDataBound(object sender, GridViewRowEventArgs e)  
{  
   LinkButton lb = e.Row.FindControl("MarkAsCompleteButton") as LinkButton;  
   ScriptManager.GetCurrent(this).RegisterAsyncPostBackControl(lb);  
}  

This also requires that ClientIDMode="AutoID" be set for the LinkButton, as mentioned here (thanks to Răzvan Panda for pointing this out).

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
NakedBrunch
  • 48,713
  • 13
  • 73
  • 98
  • 1
    @Lionel mentioned something below that I found extremely helpful in addition to this answer. Inside of the `OrderGrid_RowDataBound` handler, it is smart to do a check for the current row to be a data row (since it's possible the 'LinkButton' you're looking for isn't on a header row). `if (e.Row.RowType == DataControlRowType.DataRow) { LinkButton lb = e.Row.FindControl("MarkAsCompleteButton") as LinkButton; ScriptManager.GetCurrent(this).RegisterAsyncPostBackControl(lb); } ` Otherwise you will get a NPE when you can't find an ID to that button. – bradykey Dec 03 '15 at 20:47
  • 1
    If your Gridview is out of UpdatePanel, this will not work. Use **RowCreated** instead. – gUIDo Mar 30 '16 at 05:43
6

It's probably not advised but you can make everything on the GridView work asynchronously by excluding the EventName on the AsyncPostBackTrigger so e.g.

<Triggers>
  <asp:AsyncPostBackTrigger ControlID="OrderGrid" />
</Triggers>

This will make the RowCommand event and any other event on the GridView fire asynchronously. Note as well that when you make ClientIDMode="Static" on the GridView it will cause a full postback.

Ewert
  • 301
  • 3
  • 9
  • Thanks! The `ClientIDMode="Static"` was the problem! When removing that it works again. – Adam Sep 26 '14 at 18:47
  • The note that "when you make `ClientIDMode"Static"` on the GridView, it will cause a full-postback" was incredibly helpful. This information in tandem with forcefully registering each LinkButton as an asynchronous postback control fixed it for me since I wasn't able to get rid of the `ClientIDMode="Static"` for other reasons. Thanks so much! – bradykey Aug 01 '16 at 22:22
5

My grid view is in conditional mode.

protected void gvAgendamentoExclui_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow) {
            LinkButton lnk = e.Row.FindControl("LinkButton2") as LinkButton;
            AsyncPostBackTrigger trigger = new AsyncPostBackTrigger();
            trigger.ControlID = lnk.UniqueID;
            trigger.EventName = "Click";
            UpdatePanel2.Triggers.Add(trigger);

        }
    }

And in the click event of the linkbutton I put:

protected void LinkButton2_Click(object sender, EventArgs e)
    {
        UpdatePanel2.Update();
    }
MWiesner
  • 8,868
  • 11
  • 36
  • 70
sahar
  • 51
  • 1
  • 1
1

Put the following element inside system.web element in web.config file

<xhtmlConformance mode="Transitional"/>
Sukhjeevan
  • 3,074
  • 9
  • 46
  • 89
0

I had an issue where I had one form working fine (page1), another doing whole post backs (page2). Turned out when I made the 2nd page, I had done a bit too much cut/paste, and it still had a javascript call in the form definition.

< form id="form1" runat="server" onsubmit="return checkstuff();">

But checkstuff was not defined in page 2.

deleted the onsubmit, and the partial posts started working.

In the working page - page 1, checkstuff was defined, but was just a stub, which did nothing more than return true. Just for grins, I put an alert in checkstuff, and sure enough, it is called for all submits, partial or not. And, if I changed the stub to just return false, nothing happened at all.

Point in all this, the javascript is still exercised, as if a full page is being submitted. So double check your client side scripts.

ρяσѕρєя K
  • 132,198
  • 53
  • 198
  • 213
mike
  • 1
0

this may be old but my solution was to put an update panel inside the itemTemplate and one outside the gridview as well.

the trigger should be the gridview and the outside trigger should be the gridview and PageIndexChanging. Try that.

  • In addition to your answer, you should be sure to include to include the code that you found for your solution to help future readers with the same problem. – buczek Apr 13 '16 at 22:40
0

MSDN specifies that the UpdatePanel.ChildrenAsTriggers property "[g]ets or sets a value that indicates whether postbacks from immediate child controls of an UpdatePanel control update the panel's content" (see http://msdn.microsoft.com/en-us/library/system.web.ui.updatepanel.childrenastriggers.aspx).

Since your LinkButton does not appear to be an "immediate child control," then I would recommend configuring your LinkButton as an explicit AsyncPostBackTrigger.

Below your </ContentTemplate> tag, try adding this:

<Triggers>
  <asp:AsyncPostBackTrigger ControlID="MarkAsCompleteButton" EventName="Click" />
</Triggers>
Matthew Rodatus
  • 1,393
  • 9
  • 18
-1

You need to register each controls for each RowState. 1: Register your controls for RowState = Alternate and Normal) 2: Register your controls for RowState = Edit 3: ...

ASPX:

<asp:TemplateField HeaderText="">
                <ItemTemplate>
                    <asp:LinkButton runat="server" ID="Btn1" 
                        CommandName="Edit" CommandArgument='<%# Container.DataItemIndex + ";" + Eval("idinterlocuteur") %>'><i class="fa fa-pencil-square-o"></i></asp:LinkButton>
                </ItemTemplate>
                <EditItemTemplate>
                    <asp:LinkButton ID="Btn2" runat="server" CommandName="Update" CommandArgument='<%# Container.DataItemIndex + ";" + Eval("idinterlocuteur") %>'><i class="fa fa-check"></i></asp:LinkButton>
                </EditItemTemplate>
            </asp:TemplateField>

Code behind :

protected void GridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow 
        && (e.Row.RowState == DataControlRowState.Normal 
            || e.Row.RowState == DataControlRowState.Alternate))
    {
        LinkButton Btn1 = e.Row.FindControl("Btn1 ") as LinkButton; 
        ScriptManager.GetCurrent(this.Parent.Page).RegisterAsyncPostBackControl(Btn1 );
    }
    if (e.Row.RowType == DataControlRowType.DataRow 
        && e.Row.RowState == DataControlRowState.Edit)
    {
        LinkButton Btn2 = e.Row.FindControl("Btn2 ") as LinkButton;
        ScriptManager.GetCurrent(this.Parent.Page).RegisterAsyncPostBackControl(Btn2 );      
    }
}