title: Trouble with user selection of records in ASP.NET GridView
body: <p><strong>Goal</strong>
  What I need is to display a SQL DataTable to the user on a webpage through ASP.NET and allow them to select a number of rows very quickly and easily, and then hit any of a number of different buttons to signify different operations. The selected rows are to be sent off to be processed (generally sent to a webservice or similar through codebehind). This is a somewhat generic solution, as I will be using this same setup in many places - thus the data, and the available operations will be different.</p>
  
  <p>The goal is to be able to know basically nothing about the data - that is for the user to understand. If this concept is already impossible (though I believe it is not), please let me know.</p>
  
  <p>Pulling from T-SQL (SQL Server 2008 R2 or later).
  Using ASP.NET to make aspx webpage. Codebehind is done in VB.NET, in both cases we're using 4.0
  I'm fluent in C# and VC++, so if you can't easily translate your code, don't worry about that.</p>
  
  <p><strong>The problem</strong>
  My problem has been creating a row selection process for the user which persists while sorting or paging the table, is quick for the user and relatively quick in response time, and which is reflected in the GridView's bound data (as this allows me to use a filter on a DataView to produce a DataTable for passing). If there's another way to know the selected rows then I'm all game so long as it is persistant and quick for the user.</p>
  
  <p>I'm not debugging and I'm not having syntax issues (I do not believe) - I don't know how to proceed.
  I don't necessarily need code as a solution - I need to understand if my metaphor is either bad practice, or simply uncommon and thus not well supported. In either case, what is an appropriate way to proceed? If nothing else, where do I look for a solution besides endless API and Tutorials?</p>
  
  <p><strong>My original plan</strong>
  I wanted to use asp:GridView for binding the DataTable pulled from TSQL since I can auto-generate columns. This allows me to display data without needing to know what it is. I planned to add a specific boolean Column (left most) for storing the User's row selection. Then I can simply run a filter on the DataTable to produce a DataView, get the resulting DataTable from that DataView, and pass it down the chain. </p>
  
  <p>All the columns except our specific selection one would be Read-Only. The user isn't editing data - their selecting records and view their selection side-by-side with the viewable relevant data.</p>
  
  <p>Of note, I planned to check for name collision so our added Column doesn't collide with any existing Column in the DataTable - I'd rename it as needed using 'Select' followed by an integer produced by looping through, comparing my name to other columns, incrementing as needed. </p>
  
  <p>I presumed that once I set this up, it would just handle itself: the user could click the resulting checkbox column cell's and it would change the data on the fly. The point of saving the selection was their selection persisted through sorting and paging for convenience (I save the GridView's DataSource and re-bind when necessary). It didn't really matter if the user refreshed the page and completely and lost their checkboxes - they would need to review any changes/new data, and they wouldn't need more then a brief moment to check off whatever they wanted. </p>
  
  <p>This did not happen.</p>
  
  <p>I found that AutoGenerateColumns does not produce checkboxes for boolean DataColumns. It produces text, so I end up with the word 'True' or 'False'.</p>
  
  <p>I began looking for a way to get check boxes in the cells for a boolean DataColumn. I found that for the added boolean column, I could bind an asp:CheckBoxField to it using the attribute DataField. Of course, I have to figure out how to point it at a variable DataField...</p>
  
  <pre><code>&lt;Columns&gt;
    &lt;asp:CheckBoxField DataField="Select" HeaderText="Select" 
     ReadOnly="False" SortExpression="Select"&gt;
      &lt;ItemStyle HorizontalAlign="Center" /&gt;
    &lt;/asp:CheckBoxField&gt;
  &lt;/Columns&gt;
  </code></pre>
  
  <p>However, because a GridView is designed for Row-By-Row editing, all the resulting CheckBoxes are disabled and cannot be checked. This is because their containing row is not in Edit Mdoe. I do not want to enable Row-By-Row editing using a button or similar metaphor as the user often needs to check off several rows. More clicks is bad, and annoying. They should be focused soley on their data and making their selection, not worrying about remembering to enter and end edit mode. Also, the metaphor seems poorly placed here since the checkboxes are the -ONLY- editable data - and are not part of the represented data.</p>
  
  <p>I could, of course, make a new class which inherits from GridView, overload the method which generates columns to produce checkboxes instead of text fields - but I felt there had to be a more straightforward path. Maybe this is the way to go? But maybe it would have the same editing issue as above - I'm not sure.</p>
  
  <p>So, next I tried looking at using an asp:TemplateField as a column in my GridView. This TemplateField contains an asp:CheckBox who's Checked state is based on the underlying bound data value. The issue here is trying to make changing the check-state update that bound value. I would need some way of looking up a GridView value I could then use to find the same row in the DataTable. I've seen great examples using a Primary Key. While I could assume everyone keeps a Primary Key for any possible table, this might not be the case! I could further add a Primary Key myself, but now it looks like I would be adding and removing two columns before I pass a DataTable off to a WebService instead of just one. Again, I also would need to be able to assign a Column name which is dynamic to avoid collision.</p>
  
  <pre><code>&lt;asp:TemplateField HeaderText="Select"&gt;
      &lt;ItemTemplate&gt;
        &lt;asp:CheckBox runat="server" ID="CheckBox" 
         Checked="&lt;%# DataBinder.Eval(Container.DataItem, "Select") %&gt;" 
         AutoPostBack="true" OnCheckedChanged="SelectCheckBox_CheckChanged" /&gt;
        &lt;/ItemTemplate&gt;
  &lt;/asp:TemplateField&gt;
  </code></pre>
  
  <p>I stopped myself - This path is also fairly indirect. Surely there is a much cleaner, simpler way to do this. Is it uncommon for someone to display Read-Only data where records are selected to be submitted, in one fashion or another, for processing/updating/alteration?</p>
  
  <p>Is my choice of GridView poor? I haven't yet found another good way to represent Table data.</p>