How can I access the value of my hidden Gridview column?

I have an Id column I need to access programmatically, but I don't want it to display in the GridView. I was able to hide it this way, within the Page_Load event of the code-behind:

GridView1.Columns[0].Visible = false;

...but I am not able to retrieve the value from the hidden column. I've got a select button because of setting up my GridView with this: AutoGenerateSelectButton="True"

...but when I try to access the value, it gives me an empty string:

protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
    string movieId = string.Empty;
    GridViewRow grv = GridView1.SelectedRow;
    movieId = grv.Cells[1].Text;
    . . .

How can I access that value? I even tried accessing the value at index 0, just in case the "Select" button column is considered to be at index -1, so to speak, as it is not part of the dataset), but that, too, assigns an empty string to movieId! Index 2 does work, but it's not the value I need -- it's the Movie Title.

To be plain, I AM able to hide the "ID" (MovieId) column, between "More" and "Title":

enter image description here

...but I can't access the hidden MovieId column. Being invisible shouldn't mean that it doesn't exist.

My GridView in the aspx file:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 
            OnDataBound="GridView1_DataBound" OnPreRender="GridView1_PreRender" 
            OnSelectedIndexChanged="GridView1_SelectedIndexChanged"      
            AutoGenerateSelectButton="True">
    <Columns>
        <asp:BoundField DataField="MovieId" HeaderText="Movie Id" ItemStyle- 
            Width="0%" SortExpression="MovieId" />
        <asp:BoundField DataField="MovieTitle" HeaderText="MovieTitle" 
            SortExpression="MovieTitle" />
        <asp:BoundField DataField="IMDBRating" HeaderText="IMDBRating" 
            SortExpression="IMDBRating" />
        <asp:BoundField DataField="MPAARating" HeaderText="MPAARating" 
            SortExpression="MPAARating" />
        <asp:BoundField DataField="YearReleased" HeaderText="YearReleased" 
            SortExpression="YearReleased" />
        <asp:BoundField DataField="Minutes" HeaderText="Minutes" 
            SortExpression="Minutes" />
    </Columns>
</asp:GridView>

...and in the code-behind (aspx.cs) I have:

protected void GridView1_PreRender(object sender, EventArgs e)
{
    GridView1.HeaderRow.Cells[0].Text = "MORE";
    GridView1.HeaderRow.Cells[1].Text = "ID";
    GridView1.HeaderRow.Cells[2].Text = "TITLE";
    GridView1.HeaderRow.Cells[3].Text = "IMDB";
    GridView1.HeaderRow.Cells[4].Text = "MPAA";
    GridView1.HeaderRow.Cells[5].Text = "YEAR";
    GridView1.HeaderRow.Cells[6].Text = "MINUTES";
}

...and again, in the Page_Load event I have:

GridView1.Columns[0].Visible = false;

...which does cause the ID column to "disappear" visually (and seemingly otherwise).

So the "More" (select button) column is at index 0 in the GridView, and I'm expecting ID to be at index 1 (albeit invisible).

I'm trying to grab it in the SelectedIndexChanged event like so:

protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
    string movieId = string.Empty;
    . . .
    GridViewRow grv = GridView1.SelectedRow;
    // Index 0 should be the "MORE" (Select button) column; index 1 the 
         hidden ID (MovieId) column, index 2 the Title (MovieTitle), etc.
    movieId = grv.Cells[0].Text; // movieId is "" after this line; the actual 
        text in that column is "Select"
    movieId = grv.Cells[1].Text; // movieId is "" after this line; the column 
        is invisible
    movieId = grv.Cells[2].Text; // movieId is the value in the [Movie] Title 
        column after this line; visually, this is column index 1, but I'm 
        expecting it to be actually index 2
    . . .

Upvotes: 0

Views: 1384

Answers (2)

Albert D. Kallal
Albert D. Kallal

Reputation: 49019

You don't mention if you "just" have a datagrid control, and are shoving in say a datatable.

In that case, you don't have the template structure to play with and hide the column.

GridView1.Columns[0].Visible = false;

Without the templated fields (boundcolum template), then no columns collection exists after a data bind.

But you CAN intercept each row binding event with this:

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow | e.Row.RowType == DataControlRowType.Header)
{
    GridViewRow gRow = e.Row;
    gRow.Cells(1).Visible = false;
}
}

So note how we catch either the heading row bind event, or a data row. And thus we just set the 2nd colum visible = false.

NOTE: in most cases, when you set a control visible = false, it is NOT sent to the browser. And in THIS CASE this holds true! Normally we have to use

Cells(1).Style("Display") = "none"

This will THEN hide the colum, but STILL send the data to the browser. However, in this case (and its rare), the colums are STILL avaiable, but are NOT sent/rendered in the browser. In fact this is quite perfect, since it enhances security - you don't actually send the PK value(s) to the browser - this enhances security by quite a bit. However, if you have/introduce browser side JavaScript? Then you better use style, since visible means the PK id values are NEVER sent to the browser and client side code thus can't get/use the PK values (client side with js).

Ok, so now the above will hide the column for you.

and now in your SelectedIndex change event, you find that you can still get/grab the PK value like this:

protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
Debug.Print("row id = " + GridView1.SelectedRow.Cells(1).Text);
}

So much of this answer assumes/depends on if you are just shoving in a datatable, and you don't have any asp:BoundFields in the template, say like this:

<Columns>
  <asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False" ReadOnly="True"                     
  etc. etc. etc.
</Columns>

From your information given, I have assumed you JUST dragged a gridview onto the form, and you fill it with your code from say a data table.

So, given the above? Then you have to intercept each row that "fires" during a GridView1.Databind() as per above, and that will not only hide the column, but surprising is that the cells() are STILL available, and you will find that the PK values are not even sent down to the browser side of things.

Upvotes: 1

Rohan Rao
Rohan Rao

Reputation: 2603

If you have Hidden field like this:

<asp:HiddenField Id="HiddenField1" runat="server"/>

then you have to use GridView1.SelectedRow property followed by the cell index and the value of the control (i.e. Hidden field) like this:

string movieId = ((HiddenField)Gridivew1.SelectedRow.Cells[1].FindControl("HiddenField1")).Value;

Upvotes: 1

Related Questions