mha.dk

Random thoughts of wisdom - the personal blog of Michael Holm Andersen

GridView and the RowCommand event

The GridView is a powerful control, however dealing with multiple different column types in the RowCommand event still is a little messy! – I’ve put together a small sample which utilize the most common column types.

I have a GridView which looks like this:

<asp:GridView ID="GridView1" runat="server" AllowSorting="True"
    AutoGenerateColumns="False" DataKeyNames="ItemID" DataSourceID="LinqDataSource1"
OnRowCommand="GridView1_RowCommand">
    <Columns>
        <asp:BoundField DataField="ItemID" HeaderText="ItemID" Visible="false" InsertVisible="False"
            ReadOnly="True" SortExpression="ItemID" />
        <asp:HyperLinkField DataTextField="Name" HeaderText="Produkt" DataNavigateUrlFields="ItemID"
            DataNavigateUrlFormatString="ProductView.aspx?id={0}" SortExpression="Name" />
        <asp:BoundField DataField="ItemNo" HeaderText="Varenr." SortExpression="ItemNo" />
        <asp:TemplateField HeaderText="Pris u/moms" SortExpression="DefaultPrice">
            <ItemTemplate>
                <%# CalculatePrice(Eval("DefaultPrice"), Eval("ItemID"))%>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Antal">
            <ItemTemplate>
                <asp:TextBox ID="txtQuantity" runat="server" Style="text-align: right" Width="50">1</asp:TextBox>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Discount">
            <ItemTemplate>
                <%# ShowProductDiscount(Eval("ItemID"))%>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField>
            <ItemTemplate>
                <asp:ImageButton ID="ImageButton1" CommandArgument='<%#Container.DataItemIndex %>'
                    CommandName="AddToBasket" runat="server" ToolTip="Klik for tilføje til kurv"
                    ImageUrl="~/Images/icon_addtobasket.gif" />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

Note: I have a couple of public methods which calculates the price and discount, these methods are omitted in the below code (to simply things!).

In the RowCommand (code-behind) I have this:

protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
   {
       if (e.CommandName == "AddToBasket")
       {
           // get the index for the row which fired event
           int index = Convert.ToInt32(e.CommandArgument);

           // get primary key value from gridview DataKeys collection
           int ItemID = Convert.ToInt32(this.GridView1.DataKeys[index].Value);

           // get the current GridViewRow
           GridViewRow row = (GridViewRow)((Control)e.CommandSource).Parent.Parent;

           // get the HyperLinkField column
           HyperLink hyper = row.Cells[1].Controls[0] as HyperLink;
           if (hyper != null)
           {
               string LinkText = hyper.Text;
           }

           // get the TextBox column (Find control, cast to TextBox and convert .Text to short)
           short Quantity = short.Parse(((TextBox)GridView1.Rows[index].FindControl("txtQuantity")).Text);

           // get Price (CalculatePrice() return a string which is converted to a DataBoundLiteralControl)
           DataBoundLiteralControl lit = row.Cells[3].Controls[0] as DataBoundLiteralControl; 
           if (lit != null)
           {
               float Price = float.Parse(lit.Text);
           }

       }
   }

There you have it! – The ‘trick’ is to get your hands on the GridViewRow and then cast the various row.Cells[N] to the proper type (like above with the HyperLinkField), this technique works just as well with buttonfield and checkboxfield columns.

If don’t want to “spend time” pulling out the GridViewRow, you can also take the slightly more ‘directly’ approach (as I’ve done above with the TextBox column), where I (instead of using ‘row’) uses the GridView1.Rows[index].FindControl syntax instead (I prefer pulling out the GridViewRow, though).

That’s it! – Have fun poking around that RowCommand event! :-)

Comments are closed