转自:http://www.pluralsight.com/blogs/fritz/archive/2005/06/24/11975.aspx
I've been working on a project recently that involves using the new GridView in ASP.NET 2.0 a fair amount. In general, I'm quite pleased with this new grid implementation - it feels more intuitive, more extensible, and lighter weight than the monstrosity that is the DataGrid.
I've been working on a project recently that involves using the new GridView in ASP.NET 2.0 a fair amount. In general, I'm quite pleased with this new grid implementation - it feels more intuitive, more extensible, and lighter weight than the monstrosity that is the DataGrid.
There's one thing that's bugging me, however, since I can't find a simple way to do it and it is such a common thing in Web programming that I feel I must be overlooking something: to add a command column to the grid, the handler of which uses the current row of data to perform some task. The most common thing is to have a hidden primary key field which you then access through the Cells array of the current row (at least this was the technique in 1.1 with the DataGrid).
There is a nice ButtonField that you can add to your columns that looks like it should do the trick:
<asp:ButtonField CommandName="use" HeaderText="Use" Text="Use" />
then you can add a handler for the RowCommand event of the GridView and look for the "use" command name (this seems analogous to the ButtonColumn/ItemCommand pair in the DataGrid).
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "use")
{
}
}
So far so good. The first problem is that the GridViewCommandEventArgs has no reference to the current row (you could access it in the old DataGrid's DataGridCommandEventArgs.Item property). Ok, no problem - with a little spelunking you can use the CommandSource property and walk up to its grandparent and that turns out to the be the row - not the prettiest code, but at least we have the row.
GridViewRow row = (GridViewRow)((Control)e.CommandSource).Parent.Parent;
Now, I try and grab the value of the hidden ID column at index 0 (again, a common technique with the DataGrid).
string id = row.Cells[0].Text;
But the cell has no text in it! After some spelunking in the debugger, the value of the hidden primary key column does not seem to be there at all. As you can see, it feels like I'm swimming upstream here, and that I must be missing some new feature in the GridView that provides this same functionality. If anyone knows what that is, please post a comment.
If you have the same problem and are looking for a solution, here's what I ended up doing - just using a template field with a LinkButton and passing the ID in the CommandArgument field:
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="useLinkButton"
CommandArgument='<%# Eval("id") %>' Text="Use"
runat="server" OnCommand="useLinkButton_Command" />
</ItemTemplate>
</asp:TemplateField>
protected void useLinkButton_Command(object sender, CommandEventArgs e)
{
string id = (string)e.CommandArgument;
// do task with id here
}