Thursday, November 22, 2007

Ajax UpdatePanel , GridView , CommandField

I encountered a strange problem when working with a GridView control inside an Asp.Net ajax update panel. Basically, I have a portion of code look like this

   1: <asp:UpdatePanel ID="UpdatePanel1" 
   2:                      UpdateMode="Conditional" 
   3:                      runat="server">
   4: <ContentTemplate>   
   5:  
   6: <asp:GridView id="dgIFSPServices" runat="server" PageSize="15" AllowPaging="True" AllowSorting="True"
   7:                     AutoGenerateColumns="False" Font-Size="9pt" Font-Names="Arial" width="100%" IsSortedAscending="True" BorderWidth="1px" BorderStyle="Solid"
   8:                     ForeColor="Black" DataKeyNames="IFSPServiceID"   DefaultSort="StartDate" RecordCount="0" OnRowEditing="dgIFSPServices_RowEditing">
   9:                     <Columns>
  10:                         <asp:CommandField ButtonType="Image" EditImageUrl="../../../Images/Edit.gif" ShowCancelButton="False" ShowEditButton="True"></asp:CommandField>
  11: </asp:GridView>
  12:  
  13: </ContentTemplate>
  14: </asp:UpdatePanel>

 


And in the code behind page,



   1: protected void Page_Load(object sender, EventArgs e)
   2: {
   3: if (!IsPostBack)
   4: {
   5: //Only binding data when the page is loaded at the first time.
   6: }
   7: else
   8: {
   9: }
  10: }

 


Every time, when I click the edit button in the <asp:CommandField> , the Page_Load is called twice. At the first time, IsPostBack is true, and the second time, IsPostBack is false. Since I have some special code which I definitely only want to run it when the page first loads, this double loading behavior causes some unpleasant effects.


After some extensive search, I found the answer in this post. It was decided how the command field is interpreted by the asp.net and rendered in the html page. In my example, it was rendered as



   1: <INPUT style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px;
   2:  BORDER-RIGHT-WIDTH: 0px" onclick="javascript:__doPostBack('ctl00$ContentPlaceHolderBody$IFSPReviewOld$dgIFSPServices','Edit$0')" 
   3: type="image" alt="Edit" 
   4: src="http://localhost:29162/Odh.EarlyTrack.UI/Images/Edit.gif" value="" />

The input type="image" is treated as a submit button by the browser, and will load the page once with IsPostBack=false, and onclick will load the page once again with the IsPostBack=true.


There is another alternative workaround in the post, you can subclass the linkbutton class, and use the linkbutton inside a template field to achieve the same purpose without the double post.

No comments: