title: Why is My GridView FooterRow Referencing the Wrong Row?
body: <p>I have a <code>GridView</code> and, using a fairly common method, I'm using a <code>FooterRow</code> and <code>TemplateFields</code> to provide the missing insert ability.  So far so good.</p>
  
  <p>The footer contains a TemplateField with a LinkButton to provide the postback that does the insertion.  In the handler for the LinkButton's click, the Insert() method is called on the ObjectDataSource that the GridView is bound to.  The ObjectDataSource's insert parameters are populated in the handler for its Inserting event.  The code for all of this (abridged) looks like this:</p>
  
  <p>Markup:</p>
  
  <pre><code>&lt;asp:GridView ID="gvComplexRates" runat="server" AutoGenerateColumns="False" 
                  DataKeyNames="id" DataSourceID="odsComplexMileageRates" 
                  EnableModelValidation="True" ShowFooter="True"&gt;
                  &lt;Columns&gt;
                     &lt;asp:TemplateField ShowHeader="False"&gt;
                          :
                          :
                          &lt;FooterTemplate&gt;
                              &lt;asp:LinkButton ID="addLinkButton" runat="server" CausesValidation="false"
                                  CommandName="Insert" Text="Add"&gt;&lt;/asp:LinkButton&gt;
                          &lt;/FooterTemplate&gt;
                      &lt;/asp:TemplateField&gt;
                      :
                      :
  &lt;/asp:GridView&gt;
  </code></pre>
  
  <p>Code Behind:</p>
  
  <pre><code>Private Sub gvComplexRates_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles gvComplexRates.RowCommand
  
      Select Case e.CommandName
          Case "Insert"
              odsComplexMileageRates.Insert()
      End Select
  End Sub
  
  Private Sub odsComplexMileageRates_Inserting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ObjectDataSourceMethodEventArgs) Handles odsComplexMileageRates.Inserting
      Dim fuelTypeDropDown As DropDownList = gvComplexRates.FooterRow.FindControl("ddFuelTypeInsert")
      Dim engineTypeDropDown As DropDownList = gvComplexRates.FooterRow.FindControl("ddEngineTypeInsert")
      Dim rateTextBox As TextBox = gvComplexRates.FooterRow.FindControl("tbRateInsert")
      Dim vatRateTextBox As TextBox = gvComplexRates.FooterRow.FindControl("tbVatRateInsert")
  
      e.InputParameters("expense_type_id") = ddExpenseTypeSelect.SelectedValue
      e.InputParameters("fuel_type_id") = fuelTypeDropDown.SelectedValue
      e.InputParameters("engine_type_id") = engineTypeDropDown.SelectedValue
      e.InputParameters("rate") = rateTextBox.Text
      e.InputParameters("vat_rate") = vatRateTextBox.Text
  End Sub
  </code></pre>
  
  <p>Two of the fields in my <code>FooterRow</code> are <code>DropDownLists</code> that are populated from other tables.  Again this works fine and I can add, edit and remove rows without problem.</p>
  
  <p>The problem comes when I use a modal dialog from this page to insert extra rows into the tables used to populate the <code>DropDownLists</code> in the <code>FooterRow</code>.  The insert operations work fine and the modal dialog closes and at this point I use a javascript postback (basically a call to <code>__doPostBack()</code>) so that my <code>FooterRow</code> <code>DropDownLists</code> can be updated.  The code for this is:</p>
  
  <pre><code>Protected Sub updateFuelEngineDropdowns()
      odsFuelTypes.Select()
      odsEngineTypes.Select()
      Dim dropDown As DropDownList = gvComplexRates.FooterRow.FindControl("ddFuelTypeInsert")
      dropDown.DataBind()
      dropDown = gvComplexRates.FooterRow.FindControl("ddEngineTypeInsert")
      dropDown.DataBind()
  End Sub
  </code></pre>
  
  <p>This sub, <code>updateFuelEngineDropdowns()</code>, is called from the Page Load event.  The first time I called it it worked fine.  For some reason in subsequent runs through the debugger I'm getting <code>NullReferenceExceptions</code>.  Digging into the debug object viewer it is apparent that the <code>GridView</code> <code>FooterRow</code> is referencing the row above the footer which contains no controls (at least not at this non-editing stage) and so, quite reasonably, gives my the Null reference.</p>
  
  <p>The debug QuickView expressions I use are:<br>
  <code>gvComplexRates.FooterRow.Controls(3)</code>
  <code>DirectCast(gvComplexRates.FooterRow.Controls(3),System.Web.UI.WebControls.DataControlFieldCell).Controls(1)</code></p>
  
  <p>The first of these shows a tag of <code>td</code>.  Which makes sense.  The second shows text of "10" which is the content for the row above the footer.</p>
  
  <p>Does anybody know why this is happening?</p>
  
  <p>Thanks Dan</p>