Practical ASP.NET
Getting Data Out of the GridView (and the Other Views, Too)
Peter answers a reader's question by showing how to access data inside the individual controls of the various DataViews.
Recently, a reader asked me how to get at the controls inside a GridView during
the RowDataBound event. The answer is worth enough of an explanation to hang
a column on. I'll start with the general case and finish by actually answering
the question (and by the way, if you have a question, don't hesitate to post
a comment or
e-mail me).
Retrieving Display Data
The answer depends on two things: the state of GridView and whether the column
you want is templated. For instance, to retrieve the value of a cell that isn't
in edit mode and is in a column that isn't templated, you can use the view's
Rows and Cells collection to access any Cell. Once you've got the Cell you want,
the Cell's Text property gives you the value:
Dim Region As String = _
Me.GridView1.Rows(1).Cells(1).Text
This code also works for the DetailsView.
Of course, in a GridView you probably don't want just any row -- you want the
row that contains the data the user wants to process. In the DetailsView, this
isn't a problem because only one record is displayed at a time. In a GridView,
you need to give the user the ability to "mark" a row.
The simplest solution is to check off Enable Selection on the GridView's SmartTag,
which adds a Select button to every row. When the user clicks on the Select
button for a row, you can access that row through the GridView's SelectedRow
property. With a row selected, the code to pull out a particular Cell's value
you just specify the Cell:
If Me.GridView1.SelectedRow IsNot Nothing Then
Region As String = _
Me.GridView1.SelectedRow.Cells(1).Text
End If
For the DetailsView (or the GridView, if you've enabled Selection), you can
bypass using the Cells collection but only for one column. At design time, set
the View's DataKeyNames property to the name of the field you want. Then, at
run time you can retrieve the value of the field for the selected row through
the view's SelectedValue property (in a GridView the user must select a row
first):
If Me.GridView1.SelectedRow IsNot Nothing Then
Region As String = _
Me.GridView1.SelectedValue
End If
Edit Mode and Templated Columns
But what if the GridView row is in edit mode? When a row is in Edit mode, the
Cells become populated with some control (usually a text box). For this scenario,
you need to go one step further and retrieve the control inside the Cell and
cast it to the appropriate type. For a GridView, the EditIndex property will
tell you which row is currently being edited. Fortunately, there's only one
control in a cell, so it's always Controls(0) that you want, as seen here.
But what if you've turned the column into a template column and replaced the
control in the cell? In that case, since you know the name of the control, I'd
use the FindControl method. For a TextBox named NameTextBox in a templated column,
this
code will work.
Since the FormView is, essentially, nothing but templates, you should always
use FindControl.
In Events
That leaves me back at the original question: How to access a row in the RowDataBound
event of a GridView? Many of the GridView events pass you the selected row as
one of the properties on the e parameter. You can use this property as you would
the SelectedRow:
FirstName = e.Row.Cells(1).Text
Other events won't pass you the selected Row but will pass you the index of
the affected row. For instance, the GridViewRowEditing event's e parameter passes
the NewEditIndex property (though, it appears to be off by 1 so you need to
increment it before using). You can use these indexes with the Rows property:
FirstName = Me.GridView1.Rows
(e.NewEditIndex+1).Cells(3).Text
Other events are even more obliging: The RowUpdating and RowUpdated events,
for instance, pass the values of the cells in a collection called NewValues.
As I said at the start, the correct answer is, "It depends."
About the Author
Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter tweets about his VSM columns with the hashtag #vogelarticles. His blog posts on user experience design can be found at http://blog.learningtree.com/tag/ui/.