|
Accessing the a Particular Row's TemplateColumn's Contents
| For More Information... | |
For more information on this FAQ, check out the following resources:
|
There are often times with the DataGrid when you will need to access the value in a particular column of a particular
row. One of the most common examples of this is when using the DataGrid to edit database data. In this scenario,
after the user makes a row editable, edits the values, and then clicks the Update button, you need to programmatically
determine the updated values and perform a database update.
The two DataGridColumn types you're likely to need to access values from are the BoundColumn and the
TemplateColumn. This FAQ focuses on programmatically accessing the value from a particular TemplateColumn in
a particular DataGrid row. To see how to access the values from a BoundColumn, be sure to read the
Accessing BoundColumn Contents FAQ.
This other FAQ also contains a good discussion on DataGrids and DataGridItems, and should be read prior to reading
this FAQ.
|
DataLists and Repeaters... |
|
Since DataLists and Repeaters use templates, the discussion in this FAQ is also applicable for retrieving the
value from a template in a DataList or Repeater.
|
The Contents of a TemplateColumn
Compared to the BoundColumn, TemplateColumns allow for a tremendous amount of customization. The BoundColumn, as you
likely know, simply displays the value of a DataSource field. While you can customize the font,
color, and horizontal spacing, among other things, the BoundColumn can still be described as only be able to
do one thing: display the textual content from a particular DataSource field.
The TemplateColumn, on the other hand, allows you to specify a mixture of HTML syntax and Web controls. This
mixed content then appears in the column. For example, in another FAQ, Combining
Two DataSource Fields Into One DataGrid Column, we saw how to use a TemplateColumn and some
databinding syntax to display two DataSource fields in one DataGrid column.
TemplateColumns are often the choice du jour when creating an editable DataGrid because they allow for much
more flexibility in the editing interface as well. Specifically, the TemplateColumn contains an EditItemTemplate,
which is the template that is used when the editable row is being rendered. For example, if you wanted to
display the editable interface for a column as a small TextBox Web control with an associated RequiredFieldValidator
control, you would have to use a TemplateColumn as opposed to a BoundColumn. The TemplateColumn's editing interface
could be defined thusly:
|
...
<%# DataBinder.Eval(Container.DataItem, "SSN") %>
|
In the above example, the row currently being edited will display a TextBox Web control with nine columns.
A RequiredFieldValidator is in place to ensure that the user supplies a value. All other rows will display
the SSN field in a bold font.
Now, the challenge lies in programmatically accessing the vlaue of the txtSSN TextBox Web control
when the user clicks the Update button. Recall that to access the BoundColumn's TextBox's value, we used
the following syntax within the UpdateCommand event handler:
|
Dim myTextBox = CType(e.Item.Cells(index).Controls(0), TextBox)
Dim textBoxValue as String = myTextBox.Text
| | VB.NET |
|
TextBox myTextBox = (TextBox) e.Item.Cells(index).Controls(0);
string textBoxValue = myTextBox.Text;
| | C# |
This works because when the BoundColumn is displayed in its editable mode, a single TextBox control is added as
the Cells(index) object's sole control. With the TemplateColumn, however, a bevy of controls might
be added. Where can all these controls come from? First off, a TemplateColumn can have multiple Web controls
specified within it. In our earlier example, we had two such Web controls: a TextBox and a RequiredFieldValidator.
Furthermore, realize that all HTML markup between Web controls in the TemplateColumn are rendered as LiteralControls
(including whitespace).
For example, assume our TempalteColumn looked like so:
Now, the EditItemTemplate contains two Web controls and some HTML markup. The HTML markup is SSN: ,
right before the TextBox Web control, and then the carraige return and spacing after the TextBox but before
the RequiredFieldValidator. This means our TemplateColumn will generate four controls: a LiteralControl
containing SSN: , a TextBox Web control, a LiteralControl containing a carraige return and some
whitespace, and a RequiredFieldValidator Web control. That means, if we used syntax like with the
BoundColumn, e.Item.Cells(index).Controls(0), we would get the first control in the Controls
collection, which would be a LiteralControl containing the content SSN: . In order to access the
proper TextBox we'd have to use e.Item.Cells(index).Controls(1). Of course, the precise index could
change if we edited the EditItemTemplate at a later date, which would lead to errors, which would lead to a
big ol' headache.
So, each TemplateColumn will have several controls, only one of which is the TextBox
Web control we're interested in. What we need to do to avoid having to enter a hard-coded number as a refernce to
the Controls collection, is to set the ID property of the Web control
we're interested in. In the DataGrid declaration above, we set the SSN TextBox's ID to
txtSSN. Then, programmatically, we can access this TextBox using the FindControl()
method like so:
|
Sub myDataGrid_Update(sender as Object, e as DataGridCommandEventArgs)
'Read in the value from the TemplateColumn's SSN TextBox
Dim ssnTextBox as TextBox = CType(e.Item.Cells(1).FindControl("txtSSN"), TextBox)
Dim ssnValue as String = ssnTextBox.Text
... Update the database ...
... Reset EditItemIndex to -1 and Rebind the DataGrid ...
End Sub
| | VB.NET |
|
void myDataGrid_Update(Object sender, DataGridCommandEventArgs e)
{
// Read in the values from the BoundColumn TextBoxes
TextBox ssnTextBox = (TextBox) e.Item.Cells[1].FindControl("txtSSN");
string ssnValue = ssnTextBox.Text;
... Update the database ...
... Reset EditItemIndex to -1 and Rebind the DataGrid ...
}
| | C# |
That's all there is to it! Here, we are assuming that the TemplateColumn is the second column in
the DataGrid (hence the Cells(1)).
|
Programmatically Accessing Controls in a BoundColumn |
|
To learn how to programmatically access the Web controls in a BoundColumn be sure to read the
Accessing BoundColumn Contents
FAQ!
|
|