views:

1313

answers:

5

Hello,

I have a GridView defined as follows:

<asp:GridView ID="myGridView" AutoGenerateColumns="false" runat="server"
OnLoad="myGridView_Load" OnRowCommand="myGridView_Command" OnRowEditing="myGridView_RowEditing" OnRowDeleting="myGridView_RowDeleting" DataKeyNames="ID" > 
  <Columns>
    <asp:BoundField DataField="ID" Visible="false" />
    <asp:BoundField DataField="BirthDate" Visible="false" />
    <asp:BoundField DataField="FirstName" HeaderText="First Name" />
    <asp:BoundField DataField="LastName" HeaderText="Last Name" />
    <asp:TemplateField HeaderText="Other">
      <ItemTemplate>
        <asp:LinkButton ID="editLB" runat="server" Text="edit" CommandName="Edit" />
        <asp:LinkButton ID="deleteLB" runat="server" Text="delete" CommandName="Delete" />
      </ItemTemplate>
    </asp:TemplateField>
  </Columns>   
</asp:GridView>

When a user clicks the edit button, I need to get the value of the BirthDate column. To attempt this, I have tried the following:

protected void myGridView_RowEditing(object sender, GridViewEditEventArgs e)
{
  GridViewRow row = gvUsers.Rows[e.NewEditIndex];
  DateTime birthDate = (DateTime)(row.Cells[1].Text);

  // Does not work
}

I know it has something to do with the fact that the column is not visible. However, the column must be hidden. But, I need to get that value and I'm not sure how. Can someone please help? }

A: 

The problem is that when the Visibility property of the BoundField is set to false the column isn't rendered to the client. A work around would be to use a HiddenField within a TemplateField instead.

<asp:TemplateField>
    <ItemTemplate>
        <asp:HiddenField ID="HiddenField1" runat="server" Value='<%# Eval("BirthDate") %>' />
    </ItemTemplate>
    <EditItemTemplate>
        <asp:HiddenField ID="HiddenField1" runat="server" Value='<%# Eval("BirthDate") %>' />
    </EditItemTemplate>
</asp:TemplateField>

protected void GridView_RowEditing(object sender, GridViewEditEventArgs e)
{
    GridViewRow row = GridView.Rows[e.NewEditIndex];     
    HiddenField  hidden = (HiddenField)row.Cells[0].FindControl("HiddenField1");
    DateTime birthDate = Convert.ToDateTime(hidden.Value);
}

EDIT

The above method still renders the column in the table, so you end up with an empty column. It works but not the best solution, here's a way the hide the BirthDate field but still get its value in the RowEditing event handler. Just keep in mind that the BirthDate is still rendered to the client, just not displayed.

<style type="text/css">
    .hide
    {
        display:none;
    }
</style>

<asp:BoundField DataField="BirthDate"><ItemStyle CssClass="hide"/></asp:BoundField>

protected void GridView_RowEditing(object sender, GridViewEditEventArgs e)
{
    GridViewRow row = GridView1.Rows[e.NewEditIndex];
    DateTime birthDate = Convert.ToDateTime(row.Cells[1].Text);
}
Phaedrus
A: 

this is one way to get data from underlying data

protected void myGridView_RowEditing(object sender, GridViewEditEventArgs e)
{
  GridViewRow row = gvUsers.Rows[e.NewEditIndex];
DateTime birthDate = Convert.ToDateTime(DataBinder.Eval(row.DataItem, "BirthDate"));
}
Saar
I don't think the DataItem is populated outside of a data binding context. Inside of the RowEditing event handler DataItem will be null.
Phaedrus
A: 

I have done something like this (adapting to your example):

string[] keyList = new string[1];   
keyList[0] = "BirthDate";  
myGridView.DataKeyNames = keyList;

I then bound the GridView with a DataTable that has a column named "BirthDate". The data under this column would be stored under the DataKeyName specified above.

To get the desired value, I would do something like this:

protected void myGridView_RowEditing(object sender, GridViewEditEventArgs e)  
{   
  DataKeyArray keyList = myGridView.DataKeys as DataKeyArray;
  if (keyList != null)       
    DateTime birthDate = keyList[e.NewEditIndex];    
}

I realize that this doesn't involve hidden fields, however.

Jimmy W
DataKeyNames property is used to uniquely identify each row, it should be used for Primary Keys.
Phaedrus
Excellent point. When I used DataKeyNames that's exactly what I used them for.
Jimmy W
A: 

I would use the hiddenfield suggestion that Phaedrus suggested, and then in your code behind; use something like this:

GridViewRow row = gvUsers.Rows[e.NewEditIndex];
var hfBirthDate = (HiddenField)row.FindControl("hfBirthDate");
DateTime birthDate = DateTime.Parse(hfBirthDate.Value);
Jim B
A: 

Check out the following article that shows how to access GridView invisible columns:

http://www.highoncoding.com/Articles/178%5FAccess%5FGridView%5FInvisible%5FColumns.aspx

The idea is to basically use a TemplateField column instead of a BoundColumn.

azamsharp