in an asp.net gridview, should autogeneratecolumns=true ignore datakeys?

4.4k Views Asked by At

My question is two-fold: firstly, is it a mistake by Microsoft that when the autogeneratecolumns=true attribute of an asp.net gridview is set, columns are generated even for fields listed in the datakeynames attribute? Surely that is contrary to the whole rationale for datakeys? Secondly, is there a way to use datakeys without having to explicitly list all the non-datakey columns in the grid as bound fields, which is tedious and bad for maintenance?

In the light of AVD's comment, I will give an example: suppose I have this query as the source for my grid

SELECT intAssessmentElementID, strModuleCode, strAssessmentElement, 
Weighting, intSemester, SubmissionDate FROM tblAssessmentElements

and I don't want to display intAssessmentElementID. Here is my gridview definition

        <asp:GridView ID="grdAssessmentElements" runat="server" DataKeyNames="intAssessmentElementID">
           <Columns>
           <asp:BoundField HeaderText="Module Code" DataField="strModuleCode" />
           <asp:BoundField HeaderText="Element" DataField="strAssessmentElement" />
           <asp:BoundField HeaderText="Weighting" DataField="Weighting" />
           <asp:BoundField HeaderText="Semester" DataField="intSemester" />
           <asp:BoundField HeaderText="Submission Date" DataField="SubmissionDate" />
            </Columns>
        </asp:GridView>

Writing out those bound fields is tedious, and if I add a field to the query, I have to remember to add it to the grid definition too. With autogeneratecolumns=true, the update would be automatic. But autogeneratecolumns=true generates all columns, even those listed in datakeynames. I think this is contralogical. I would like a way to use both autogeneratecolumns=true and datakeynames, but with the datakeynames columns not appearing. I have seen numerous suggestions to hide the columns after data bind, but they don't work for me and others When the columns are auto-generated, they don't appear to be available/generated even in PreRender.

1

There are 1 best solutions below

4
On BEST ANSWER

The very definition of AutoGenerateColumns is as follows (emphasis mine):

Gets or sets a value indicating whether bound fields are automatically created for each field in the data source.

If you don't want to display all of the fields, you must manually create a DataField for each one you want to display. Unfortunately, AutoGenerateColumns and DataKeyNames are unaware of each other.

Another option for you is to use AutoGenerateColumns, but hide the cells you don't want to see as they are created. First, hook onto the RowCreated event.

<asp:GridView ID="grdAssessmentElements" runat="server"
    DataKeyNames="intAssessmentElementID"
    OnRowCreated="grdAssessmentElements_RowCreated">

Then in this event, hide the cell. The problem with this is that you must hardcode indexes. For example, if you know the first column is one you want to hide.

protected void grdAssessmentElements_RowCreated(object sender, GridViewRowEventArgs e)
{
    e.Row.Cells[0].Visible = False;
}

This still does not solve the problem of having to change the code as soon as you start returning a new column, however. As soon as you add a new column and you don't want to show it, you must add more code.

To answer your second question, you can use DataKeys whenever you want. You could use it with AutoGenerateColumns and hide the cells yourself. Or you could use it and explicitly list your columns.

I prefer listing each column. That way if the query ever changes without your knowledge, you know that your GridView will never display something it shouldn't. I have never found it to be as tedious as you seem to be thinking.