Accessing DataGrid Information
By Luis Estrada
Published: 5/10/2002
Reader Level: Beginner
Rated: 4.33 by 3 member(s).
Tell a Friend
Rate this Article
Printable Version
Discuss in the Forums

The Problem

So many articles explain all the various ways of getting your information into a DataGrid.  This article will explain how to get information out of your datagrid.  It is not exactly clear how to get information out of your DataGrid once it is bound and filled.  So, how do I read the contents of a particular column when the user selects an item? 

The Setup

My page has a DataGrid called dgAges, a Label called lblName, and another Label called lblAge.  It has a Select column, a Bound column (Name), and a Template column (Age). 
 
...
<asp:DataGrid
   id="dgAges"
   runat="server"
   AutoGenerateColumns="False"
   OnSelectedIndexChanged=" SelectionChanged">

   <Columns>
      <asp:ButtonColumn Text="Select" HeaderText="" CommandName="Select" />
      <asp:BoundColumn DataField="Name" HeaderText="Name" />
      <asp:TemplateColumn HeaderText="Age">
         <ItemTemplate>
            <%# Container.DataItem("Age") %>&nbsp;yrs. old
         </ItemTemplate>
      </asp:TemplateColumn>
   </Columns>
</asp:DataGrid>

<P>&nbsp;</P>
<P><STRONG><U>Current Selection:</U></STRONG></P>
<P><STRONG>Name:</STRONG>&nbsp; <asp:Label id="lblName" runat="server"></asp:Label></P>
<P><STRONG>Age:</STRONG>&nbsp; <asp:Label id="lblAge" runat="server"></asp:Label></P>
...

What I want to do is set the Text property of the Labels to the respective values when a row is selected.  The OnSelectedIndexChanged property of dgAges specifies that the SelectionChanged sub routine will run when an item is selected. 

The BoundColumn vs. The TemplateColumn

The first thing you'd think to try is to use a cell's Text property to get whatever text is there.  This works only for the Bound Column:

...
Protected Sub SelectionChanged()
   'Bound Column... This works
   lblName.Text = dgAges.SelectedItem.Cells(1).Text

   'Template Column... This doesn't work
   lblAge.Text = dgAges.SelectedItem.Cells(2).Text
End Sub
...

That is because .NET sees the contents of the BoundColumn as Text and the contents of the TemplateColumn as a DataBoundLiteralControl.  In fact, .NET always sees the contents of Template columns as a collection of server controls.  To correctly set lblAge's Text, you'd have to acess the DataBoundLiteralControl's Text property.  Each cell has a collection of Controls that we can access.  Keep in mind that this collection returns an object of type Control, so you will have to cast it to the type you want to use; in this case a DataBoundLiteralControl.  Here's how it is done: 

...
Protected Sub SelectionChanged()
   'Bound Column... This works
   lblName.Text = dgAges.SelectedItem.Cells(1).Text

   'Template Column... This works
   lblAge.Text = CType(dgAges.SelectedItem.Cells(2).Controls(0), DataBoundLiteralControl).Text
End Sub
...

Don't be discouraged if you're thinking "I would never have guessed DataBoundLiteralControl."  The important thing is to know how it works.  Now we know .NET puts the contents of Template columns in the Controls collection of each cell, and we know to cast the controls to the types we need to utilize all their methods and properties.

Note that the Template column isn't always going to have a DataBoundLiteralControl.  Obviously, if you have a control in your template (say a TextBox in an EditItemTemplate), that particular control will be in the Controls collection of that cell.

The Better Setup

Knowing what I know now, I would have set up the whole page a little differently.  First of all, I would have used a Label control in my Template column, so I know what I'm getting instead of having to guess or otherwise figure out that it is a DataBoundLiteralControl:

...
<asp:DataGrid
   id="dgAges"
   runat="server"
   AutoGenerateColumns="False"
   OnSelectedIndexChanged=" SelectionChanged">

   <Columns>
      <asp:ButtonColumn Text="Select" HeaderText="" CommandName="Select" />
      <asp:BoundColumn DataField="Name" HeaderText="Name" />
      <asp:TemplateColumn HeaderText="Age">
         <ItemTemplate>
            <asp:Label RunAt="server" ID="lblThisAge" Text='<%# Container.DataItem("Age") %>' />&nbsp;yrs. old
         </ItemTemplate>
      </asp:TemplateColumn>
   </Columns>
</asp:DataGrid>

<P>&nbsp;</P>
<P><STRONG><U>Current Selection:</U></STRONG></P>
<P><STRONG>Name:</STRONG>&nbsp; <asp:Label id="lblName" runat="server"></asp:Label></P>
<P><STRONG>Age:</STRONG>&nbsp; <asp:Label id="lblAge" runat="server"></asp:Label></P>
...

Please note the following:

  1. I know the type of the control in the Template column because I specified it:  <asp:Label ...
    This means I no longer have to guess the type of the control in the Template column.
  2. I know the ID of the information I want to retrieve: ID="lblThisAge" ...
  3. I can use the FindControl() method of the item to retrieve my Label based on its ID.
    This means that I don't have to guess which order the control appears in the cell's Controls collection and I don't have to keep track of which column number my Age column is.
...
Protected Sub SelectionChanged()
   'Bound Column... This works
   lblName.Text = dgAges.SelectedItem.Cells(1).Text

   'Template Column... This works
   lblAge.Text = CType(dgAges.SelectedItem.FindControl("AgeText"), Label).Text
End Sub
...

The Conclusion

The problem was that I assumed the Text property of the cell would always return the text in the cell.  If you think about it, you'll realize that with all the complex things you can do in a Template column, and all the complex controls you can have in a Template column, the Text property wouldn't suffice as a means of retrieving the information you need.  With this understanding, you can then explore all the options you have in how to retrieve and/or manipulate information in your DataGrid.



Marketplace
(Sponsored Links)
What are the green links?
   



 
Copyright © 2007 CMP Tech LLC |
Privacy Policy (4/10/06) | Your California Privacy Rights (4/10/06) | Terms of Service | Advertising Info | About Us | Help