Introduction
I ran into a problem the other day where I needed to catch the value of a clicked cell in a GridView
. By default, the RowCommand
contains the RowIndex
in the CommandArgument
, but there is no way of knowing which column fired the event. The solution was found in setting the CommandArgument
value of the cell at run-time when you bind the rows of the GridView
. This article will show you how to do this in a very quick and simple way.
Background
Thanks to forum.asp.net, I was pointed into the right direction by setting the CommandArgument
of the cell during the RowDataBound
event. Question was, of courseā¦ how? Until by accident I ended up with the solution I will present now.
The Application
I will use a very small application to show how to do this. The application shows the data of music groups from an XML file with the help of the XmlDataSource
object. I would never use those DataSource
objects in real applications, but they are great to put something together in just a few minutes for prototyping purposes. The data exist for the band name and four members. When clicking on a member, the name is displayed in a label above the GridView
.
I am not going into how to bind the XML file to the GridView
. There are many articles on something called the Internet that handle this topic. I will just show you the RowDataBound
and RowCommand
event handlers of this GridView
. (I also found out how hard it is to find four-member groups when you actually need them.)
To run the example, download the source, open the project file, and run it through Visual Studio 2005.
RowDataBound
The RowDataBound
event is triggered every time a row of the GridView
is bound to data. It is a great place to make some last changes to the data before it is displayed to the user.
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
((LinkButton)e.Row.Cells[1].Controls[0]).CommandArgument =
((LinkButton)e.Row.Cells[1].Controls[0]).Text;
((LinkButton)e.Row.Cells[2].Controls[0]).CommandArgument =
((LinkButton)e.Row.Cells[2].Controls[0]).Text;
((LinkButton)e.Row.Cells[3].Controls[0]).CommandArgument =
((LinkButton)e.Row.Cells[3].Controls[0]).Text;
((LinkButton)e.Row.Cells[4].Controls[0]).CommandArgument =
((LinkButton)e.Row.Cells[4].Controls[0]).Text;
}
}
The above code checks first if the row is of type 'DataRow
'. Next, we navigate to the different cells of the row and cast the first control to a LinkButton
. This cast is very important and depends on what type of button you use in your GridView
. If you set the type to 'button', then you need to cast the control to a Button
. In my case, I use the 'link' type so I have to cast it to a LinkButton
control. Once you cast it to the correct control, you can set the CommandArgument
property to the Text
value without any problems, as shown above.
RowCommand
Once you set the CommandArgument
, the only thing left to do is retrieve it when clicking on the link. Clicking on the link fires a normal RowCommand
event, but now, you find that the CommandArgument
is not the row index, but the text of the clicked cell. Of course, you need to set the CommandName
of all ButtonField
s to the same name. Next, you just do the same as you always do with the RowCommand
, as shown below:
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "ShowMember")
{
lblResult.Text = "You clicked Member '" + e.CommandArgument.ToString() + "'";
}
}
Conclusion
As you can see, a very simple solution, that unfortunately took me almost a whole day to figure out. This, of course, included waiting for response out from America. Why do those guys always sleep when we are awake?? My biggest problem was to access the control and the CommandArgument
property when binding the row. I was actually trying to convert it to a ButtonField
, until (I still don't know why) I suddenly mistyped and converted it to a LinkButton
. Of course, now it all makes perfect sense to me. Depending on what type of button you select in the GridView
, that is the kind of control generated at run-time and needs to be used when referring to it. This discovery helped me a lot in my current project, and I hope it will help others as well who fall on this article. This is my first article to The Code Project. For years, this has become one of my main resources, so I thought it is time to give something back (or at least try to).