GridView Template - How to Grab Data from Selected Row

5.9k views Asked by At
<asp:TemplateField>    
    <ItemTemplate>
        <table width="540" cellpadding="5">
        <tr>
            <td align="left" style="width:60%;">
                <img src='PurchaseHandler.ashx?ProductID=<%# Eval("ProductID")%>' 
                    alt="<%# Eval("ProductName") %>" />
            </td>
            <td align="left">
                 <h3 style="text-align:left;">
                     <asp:Label ID="nameLabel" runat="server" 
                         Text='<%# Eval("ProductName") %>'  />
                 </h3>
                 <asp:Label ID="priceLabel" runat="server" Text='<%# Eval("Price") %>' />  
                 <br />
                 <asp:LinkButton ID="cartLink" runat="server" Text="<b>Add to Cart</b>"
                     CommandName="Add" CommandArgument='<%# Eval("ProductID") %>' />
            </td>
        </tr>
        </table>
    </ItemTemplate>
</asp:TemplateField>

I'm using a shopping cart business object which contains fields not used for display in the GridView. What I'm attempting to do next in the RowCommand event handler is to retrieve the rest of the data fields from the selected row. This gives me the correct product ID from the selected row:

if (e.CommandName == "Add")
{
    int productID = 0;
    int.TryParse(e.CommandArgument as string, out productID);

    // Big blank!
}

How can I grab the rest of the data fields from the selected row to populate my cart? By way of explanation, I can probably use the productID to dig into the DataSet pulled from Session state, and get the data that way. However, what I'm trying to determine is if there is a syntax similar to this that can be used in this situation?

DataRow[] rows = ds.Tables[0].Select("ProductID=" +
                     gridProducts.SelectedDataKey.Values["ProductID"].ToString());
DataRow row = rows[0];
1

There are 1 answers

3
David Hall On BEST ANSWER

One way to do this would be to use the command argument to store the row index (perhaps setting it in the on row created event).

You could then use code as below to access your row (code snipped from MSDN):

  // Convert the row index stored in the CommandArgument
  // property to an Integer.
  int index = Convert.ToInt32(e.CommandArgument);

  // Retrieve the row that contains the button clicked
  // by the user from the Rows collection. Use the
  // CommandSource property to access the GridView control.
  GridView customersGridView = (GridView)e.CommandSource;
  GridViewRow row = customersGridView.Rows[index];

If you need to keep your command argument as the product id then you can use the code below to access the row:

GridViewRow row = (GridViewRow)(((LinkButton)e.CommandSource).NamingContainer);

You can then use the FindControl() method of the GridViewRow to select the controls that you need.

Label priceLabel = row.FindControl("priceLabel") as Label;

Edit after comments from OP

So if I'm correct, you want to access the DataItem of your row?

I don't think this is possible within a RowCommand event handler - I did a little bit of digging on other forums and apparently this property is only not null during DataBind - MSDN has this to say:

The DataItem property is available only during and after the RowDataBound event of a GridView control.

Looks like your method or something similar is the only way of linking back to the original objects in the RowCommand (hopefully someone proves me wrong)