Introduction
In previous articles, we have limited the discussion to very elementary use of DataGrid
control. This was just to get started and have some kind of foundation to build on. Now, we will start delving into some intermediate level of use. In this article, we will focus on one question.
Can I Select the Columns, from the Datasource, Which Should Be Rendered?
The datasource for your data grid may have quite a few data columns. But you may not want to display the information from all of them. And in some cases, you may want to combine the information from multiple fields to display in one data column of the grid. And extend our example, we have added one more field to the dataset. This field contains the URLs for the article titles in the dataset. Now when we want to display the list of articles, there is no point displaying the long URLs to the client. It would be nice if we could present the data in such a form that the client only sees the titles and click on them to access the URLs. That means, we need a way so that Hyperlink
data field from the datasource gets combined with Title
field in one DataColumn
.
DataGrid
control exposes AutoGenerateColumns
attribute. By default, this attribute value is set to true
. What this means is that when DataGrid
gets databound to the source, it will render all the data fields that it can. Notice that we said render fields that it can. This is how it works.
When you bind a data source to DataGrid
control, it generates BoundColumn
objects for each data column. As the name implies, a BoundColumn
is a column in the grid and is bound to a data field in the datasource. It is used to render information in text format. That means if a field contains data that is not of Primitive
types, String
, DataTime
and Decimal
type, it will exclude those columns from rendering. This does not mean that you can't have any other data types in the source. But to render those data types, you will need to use TemplateColumn
. We will discuss that in our next article.
There are five types of columns that you can add to DataGrid
control:
EditCommandColumn
HyperLinkColumn
BoundColumn
ButtonColumn
TemplateColumn
The names of the columns are very descriptive. If you want to render a field in a form that does not fit in the first four types, then you can use TemplateColumn
for that.
Back to our original question. How do we control what columns to display? Here are the steps that you need to follow to accomplish this. First, we will show this can be done using asp
design time tags. And then, we will show how to do it programmatically.
- Set
AutoGenerateColumns
attribute to false
. - Add
Column
tag to asp:DataGrid
tag. - Now add your
BoundColumn
tags for the data fields that you want to render. For example, we want to render Index, Title
and Description
fields. Two fields, Title
and Description
can be simply displayed by adding BoundColumn
tags. But we want to combine Title
field with Hyperlink
field to render the information as a
HTML tag so that user can click on the links to go to that article URL. So we added HyperLinkColumn
column tag to Control
collection.
<asp:DataGrid ID="DefaultGrid" Runat="server" AutoGenerateColumns=False>
<Columns>
<asp:BoundColumn DataField="Index" ReadOnly=True HeaderText="#">
</asp:BoundColumn>
<asp:HyperLinkColumn DataNavigateUrlField="Hyperlink"
DataTextField="Title" HeaderText="Title">
</asp:HyperLinkColumn>
<asp:BoundColumn DataField="Description"
ReadOnly=True HeaderText="Description">
</asp:BoundColumn>
</Columns>
</asp:DataGrid>
For more information on all the properties that you can set for these bound columns, please refer to .NET Framework documentation.
Now we will show how this can be accomplished programmatically in a code behind file. Now you don't have to supply any Columns
or BoundColumn
tags in aspx
file. All the steps described earlier will be done programmatically. We have created InitializeBoundColumns
method in our class that adds the columns to Columns
collection of DataControl
control.
private void InitializeBoundColumns()
{
DefaultGrid.AutoGenerateColumns = false;
BoundColumn indexCol = new BoundColumn();
indexCol.DataField = "Index";
indexCol.HeaderText = "#";
BoundColumn descCol = new BoundColumn();
descCol.DataField = "Description";
descCol.HeaderText = "Description";
HyperLinkColumn urlCol = new HyperLinkColumn();
urlCol.DataTextField = "Title";
urlCol.DataNavigateUrlField = "Hyperlink";
urlCol.HeaderText = "Title";
DefaultGrid.Columns.Add(indexCol);
DefaultGrid.Columns.Add(urlCol);
DefaultGrid.Columns.Add(descCol);
}
Some Important Observations
AutoGenerateColumns Value Should be Set before You Bind Datasource to DataGrid Control
If you are using design time method of specifying columns, then this is not a problem because you will specifying this value in asp:DataGrid
tag itself. But if you are doing it programmatically, set this attribute value before you call DataBind
method on DataGrid
control object.
DefaultGrid.AutoGenerateColumns = false;
DefaultGrid.DataBind();
Not Setting the AutoGenerateColumns Attribute
If you don't set AutoGenerateColumns
attribute before control getting data bound, you will end up with a data grid with all the data columns in data source plus the columns you specified in Columns
collection.
BoundColumn Control Order Is Important
Order in which BoundColumn
controls are added is important. They get rendered in the order in which they were added. So if you want a data column to be rendered before another field, then make sure that it is added to Columns
collection in that order.
Empty Columns Collection
Columns
collection will be empty if AutoGenerateColumns
attribute is set to true
and you don't add any columns explicitly. What this means is that if you don't add any bound columns to Columns
collection of the control, it will be empty. The control does not populate this controls collection if all the data columns are generated automatically. Therefore, if you are planning to control the order and rendering of columns programmatically, then make sure that you have set AutoGenerateColumns
value to false
and added the required data columns to Controls
collection.
Explicitly Added and Automatically Added Column Combinations
If you use combination of explicitly added columns and automatically generated columns, then explicitly declared columns are rendered first. This means that you have set AutoGenerateColumns
to true
and also added Columns
tag to add columns explicitly. You may use this kind of combination when you want to combine couple of data fields to generate one field. We will discuss it in the next article when we describe use of TemplateColumn
.
HeaderText Property and Explicitly Added Columns
If you explicitly add columns, then set value of HeaderText
property to display header for that data column. When columns are automatically generated and ShowHeader
property is set to true
, then data column's name is used as header text. But for explicitly added, you will have to supply the header text.
Rendering Properties Specified for Explicitly Added Columns
Rendering properties specified for explicitly added columns, only affects the column and not the contained HTML tag. What this means is that if you set the value of any property like CssClass
for a bound column like HyperLinkColumn
, it is applied to <td>
cell that contains <A>
tag. So if you have any HTML tag contained in that table cell that cannot inherit style from the container, then you may have to use TemplateColumn
to control its rendering.
History
- 20th April, 2002: Initial version
License
This article has no explicit license attached to it, but may contain usage terms in the article text or the download files themselves. If in doubt, please contact the author via the discussion board below. A list of licenses authors might use can be found here.