title: Adding dynamic columns to an ASP.NET Gridview
body: <p>I'm having a problem dynamically adding columns to a GridView.  I need to change the layout -- i.e. the included columns -- based on the value in a DropDownList.  When the user changes the selection in this list, I need to remove all but the first column and dynamically add additional columns based on the selection.</p>
  
  <p>I have only one column defined in my markup -- column 0, a template column, in which I declare a Select link and another application specific LinkButton.  That column needs to always be there.  When the ListBoxSelection is made, I remove all but the first column and then re-add the desired columns (in this sample, I've simplified it to always add a "Title" column).  Here is a portion of the code:</p>
  
  <pre><code>RemoveVariableColumnsFromGrid();
  BoundField b = new BoundField();
  b.DataField = "Title";
  this.gvPrimaryListView.Columns.Add(b);
  this.gvPrimaryListView.DataBind();
  
  
  private void RemoveVariableColumnsFromGrid() {
      int ColCount = this.gvPrimaryListView.Columns.Count;
      //Leave column 0 -- our select and view template column
      while (ColCount &gt; 1) {
          this.gvPrimaryListView.Columns.RemoveAt(ColCount - 1);
          --ColCount;
      }
  }
  </code></pre>
  
  <p>The first time this code runs through, I see both the static column and the dynamically added "Title" column.  However, the next time a selection is made, the first column is generated empty (nothing in it).  I see the title column, and I see the first column to its left -- but there's nothing generated within it.  In the debugger, I can see that gvPrimaryListView does indeed still have two columns and the first one (index 0) is indeed a template column.  In fact, the column even retains it's width which is set as 165px in the markup below (for debugging purposes).</p>
  
  <p>Any ideas?</p>
  
  <pre><code>&lt;asp:GridView ID="gvPrimaryListView" runat="server" Width="100%" AutoGenerateColumns="false"
      DataKeyNames="Document_ID" EnableViewState="true" DataSourceID="odsPrimaryDataSource"
      AllowPaging="true" AllowSorting="true" PageSize="10" OnPageIndexChanging="activeListView_PageIndexChanging"
      AutoGenerateSelectButton="False" OnSelectedIndexChanged="activeListView_SelectedIndexChanged"
      Visible="true" OnRowDataBound="CtlDocList_RowDataBound" Font-Size="8pt" Font-Names="Helvetica"&gt;
      &lt;Columns&gt;
          &lt;asp:TemplateField ShowHeader="false"&gt;
              &lt;ItemTemplate&gt;
                  &lt;asp:LinkButton EnableTheming="false" ID="CtlSelectDocRowBtn" runat="server" Text="Select"
                      CommandName="Select" CssClass="gridbutton" OnClick="RowSelectBtn_Click" /&gt;
                  &lt;asp:ImageButton EnableTheming="false" ID="DocViewBtn" runat="server" ImageUrl="../../images/ViewDoc3.png"
                      CssClass="gridbutton" CommandName="Select" OnClick="DocViewBtn_Click" /&gt;
              &lt;/ItemTemplate&gt;
              &lt;ItemStyle Width="165px" /&gt;
          &lt;/asp:TemplateField&gt;
      &lt;/Columns&gt;
      &lt;EmptyDataTemplate&gt;
          &lt;asp:Label ID="Label6" runat="server" Text="No rows found." SkinID="LabelHeader"&gt;&lt;/asp:Label&gt;
      &lt;/EmptyDataTemplate&gt;
  &lt;/asp:GridView&gt;
  </code></pre>
  
  <hr>
  
  <p>Just some additional information.</p>
  
  <p>It has nothing to do with the fact that it is the first column but everything to do with the fact that it is a TemplateField.  If I put a normal column to the left (in the markup) and shift the TemplateField column to the right, the first column renders fine, and the (now second) TemplateField column disappears.</p>
  
  <p>Another strange thing -- the problem doesn't happen the first postback -- OR THE SECOND -- but it starts on the third postback and then continues for subsequent postbacks.  I'm stumped.</p>