DevCity.NET - http://devcity.net
Using ASP.NET DataGrid Web Server Control
http://devcity.net/Articles/186/1/article.aspx
Misha Zhutov

Misha Zhutov works as a Software Architect for SubMain(), a division of vbCity.com, LLC.

During more than 7 years of his programmer career Misha has developed various applications including desktop, client-server and Internet development. He has been working with Microsoft technologies since 1997 and has been developing with Microsoft .NET since the Beta 2 release in 2001.

Misha has a Bachelors and a Masters degree in Radio-Electronic Engineering from Kharkov Aviation University.

His primary areas of expertise are VB.NET, C#, ASP and Visual Basic.

 
by Misha Zhutov
Published on 11/3/2005
 

It would be hard to find a web developer who doesn’t need to use a DataGrid. This control is ideal for data presentation. Besides the visualization, it provides a powerful set of possibilities to edit, delete, add and update data. ASP.NET includes a well designed, powerful DataGrid Web Server Control which makes the life of web developers easier. I remember the time when we had to implement the grid's functionallity manually in classic ASP. And, although, a lot of time has passed since first ASP.NET was released and a lot of information exists on the  web, still there are a quite a bit of questions asked on forums about DataGrid features. In this article I will demonstrate some DataGrid features such as editing, updating, deleting, sorting, paging, etc. which are quite often used by many web developers.   


Introduction

It would be hard to find a web developer who doesn’t need to use a DataGrid. This control is ideal for data presentation. Besides the visualization, it provides a powerful set of possibilities to edit, delete, add and update data. 

ASP.NET includes a well designed, powerful DataGrid Web Server Control which makes the life of web developers easier. I remember the time when we had to implement the grid's functionallity manually in classic ASP. And, although, a lot of time has passed since first ASP.NET was released and a lot of information exists on the  web, still there are a quite a bit of questions asked on forums about DataGrid features.

In this article I will demonstrate some DataGrid features such as editing, updating, deleting, sorting, paging, etc. which are quite often used by many web developers.    

Binding to data source

As usual, working with DataGrid begins with a data source. As data source, I used the well known Nwind database. Our DataGrid is bound on ‘Products’ table. Why Products table? Because it contains relationships with other tables such as ‘Categiries’, ‘OrderDetails’ and ‘Suppliers’.
Here is a screenshot of the tables relationship:


It models a  situation when  thedeveloper needs to display some related tables in DataGrid.

For binding, every table in the database should be converted to a DataTable object. How to do it? We need to create a new DataSet item, drag an object from Server Explorer. Visual Studio generates a DataSet class which contains a DataTable you entered.

Is that all? No. As we are going to do some operations on every table, it will be nice to create a small business layer. So, for every table, I created a component class which encapsulates logic for select, delete update a data from particular table.

DataGrid Layout

Let’s take a look at the HTML code in the ASPX page that creates the DataGrid:

<asp:datagrid id=ProductsDataGrid runat="server" 
  PageSize="<%# PageSize%>"
  AllowPaging="True"
  AllowSorting="True"
  BorderStyle="None"
  AutoGenerateColumns="False"
  DataSource="<%# Products %>"
  HorizontalAlign="Left"
  CellPadding=3
  Width="90%"
  BackColor="White"
  BorderColor="Black"
  PagerStyle-Mode="NextPrev" >

<ItemStyle Wrap="True" BorderStyle="None" CssClass="BodyText"></ItemStyle>
<HeaderStyle HorizontalAlign="Center" CssClass="ListHeader"></HeaderStyle>

As we see, DataGrid has powerful built-in features for customizing layout . You can play with such features by changing ItemStyle, HeaderStyle, color schema etc. After loading a page, the user is presented a DataGrid like this:

 

DataGrid columns creation

DataGrid has different column types which determine the behavior of the columns in the control, such as BoundColumn, ButtonColumn, EditCommandButton, HyperLinkColumn and TemplateColumn.
In this demonstration I used a TemplateColumn type which provides the most freedom in customization. This alloww you to use any controls inside a data row.
TemplateColumn has its own layout tuning and two different set of controls for view and edit mode.
Let’s take a look at the HTML code in the ASPX page that creates the DataGrid columns:

<asp:TemplateColumn ItemStyle-Wrap="true" 
SortExpression="ProductName"
HeaderText="Product Name">

  <ItemTemplate>
    <asp:Label id=Label3 runat="server"
Text='<%# DataBinder.Eval(Container, "DataItem.ProductName") %>'>
</asp:Label>
  </ItemTemplate>
  <EditItemTemplate>
    <asp:RequiredFieldValidator id="RequiredFieldValidator1"
runat="server"
  ErrorMessage="Product name is empty."
  Display="None"
ControlToValidate="ProductNameTextBox">
Product name is empty.
    </asp:RequiredFieldValidator>



    <asp:TextBox id="ProductNameTextBox" Width="110"
MaxLength="40" runat="server"
Text='<%# DataBinder.Eval(Container, "DataItem.ProductName") %>'>
    </asp:TextBox>
    <asp:Label id="ProductIDLabel" runat="server" Visible=False
Text='<%# DataBinder.Eval(Container, "DataItem.ProductID") %>'>
</asp:Label>
  </EditItemTemplate>
</asp:TemplateColumn>

As we see here, the column has two different control sets – Label for viewing mode and TextBox with a validator for edit mode. Required validator prevents the user from leaving a field empty when editing and will be described below.
Some columns are bound on table columns that have relationships with another tables. For such purposes, I used a DropDownList control in edit mode that bounded on relation table.
Let’s take a look at the HTML code that sets up a DropDownList control in edit mode:

<asp:TemplateColumn SortExpression="CategoryID" HeaderText="Category">
  <ItemTemplate>
    <asp:Label id="Label33" runat="server" Width="150"
Text='<%# GetCategoryName(DataBinder.Eval(Container, _
"DataItem.CategoryID"))%
>'>
    </asp:Label>
  </ItemTemplate>
  <EditItemTemplate>
    <asp:DropDownList id="CategoryDropDownList"
DataSource=<%# Categories%
DataTextField="CategoryName"
DataValueField="CategoryID"
SelectedValue=<%# DataBinder.Eval(Container, "DataItem.CategoryID")%>
Width="150" runat="server">
    </asp:DropDownList>
  </EditItemTemplate>
</asp:TemplateColumn>

After clicking the Edit link, the user is presented with a pre-populated DropDownList, which looks  like this:


 

DataGrid sorting

Sorting is quite an important built-in feature of DataGrid. It is really easy to implement a sorting functionality in DataGrid. To enable sorting in DataGrid you need to:

  • add AllowSorting="True" attribute for DataGrid
  • set SortExpression attribute from TemplateColumn element is equal to name of column in theDataTable.
  • add code in DataGrid.SortCommand Event handler to customize ascending and descending sorting:

Private Sub ProductsDataGrid_SortCommand(ByVal source As Object_
ByVal e As System.Web.UI.WebControls.DataGridSortCommandEventArgs) _
Handles ProductsDataGrid.SortCommand
   If Not 
ProductsDataGrid.Attributes(SortExpressionAttributeIs Nothing Then

     Dim currectSortExpression As String = _
     ProductsDataGrid.Attributes(SortExpressionAttribute).ToString()

     If 
currectSortExpression.StartsWith(e.SortExpression.ToString()) Then

       If Not currectSortExpression.EndsWith(DescSortOrderThen
         ProductsDataGrid.Attributes(SortExpressionAttribute= 
         String.Concat(currectSortExpressionDescSortOrder)
       Else
         ProductsDataGrid.Attributes(SortExpressionAttribute= _
         currectSortExpression.Substring(0_
         currectSortExpression.Length - DescSortOrder.Length)
       End If
     Else
       ProductsDataGrid.Attributes(SortExpressionAttribute= _
       e.SortExpression.ToString()
     End If
  Else
    ProductsDataGrid.Attributes(SortExpressionAttribute= _
    e.SortExpression.ToString()
  End If

  SortDataBind()
End Sub

Generated using PrettyCode.Encoder

DataGrid Paging

When you display quite large amounts of data, it is not convenient to scroll it. DataGrid proposed a solution for this situation - built-in paging feature.
To enable paging in DataGrid you need to:

  • add AllowPaging="True" attribute for DataGrid
  • specify PagerStyle-Mode attribute for customizing paging mode.
  • Add PagerStyle element like this:
<PagerStyle NextPageText="Next" PrevPageText="Prev" HorizontalAlign="Center"         
CssClass="PagingText"></PagerStyle>
  • Set PageSize attribute which means number of items to display on a single page of the DataGrid control
  • Add code in the DataGrid.PageIndexChanged Event handler:

Private Sub ProductsDataGrid_PageIndexChanged(ByVal source As Object_
ByVal e As System.Web.UI.WebControls.DataGridPageChangedEventArgs) _
Handles ProductsDataGrid.PageIndexChanged
    ProductsDataGrid.EditItemIndex = -1
    ProductsDataGrid.CurrentPageIndex = e.NewPageIndex
    BindDataGrid()
End Sub
Generated using PrettyCode.Encoder
After loading a page, the user is presented a ‘Prev’ and ‘Next’ links at the bottom:
 

DataGrid editing

As we already know, a TemplateColumn has two control sets for viewing and editing mode. First of all, we need to add an Edit button to DataGrid.
A column with Edit link can be added either as the first column or as last column in the DataGrid.
I prefer to add Edit link as the  DataGrid’s first column. This is because, sometimes, DataTable can have many columns and a user needs to scroll horizontally.
Let’s take a look at the HTML code in the ASPX page that creates the DataGrid column with links:

<asp:TemplateColumn>
  <ItemStyle HorizontalAlign="Center" VerticalAlign="Middle"></ItemStyle>
  <ItemTemplate>
    <asp:LinkButton id="LinkEdit" runat="server" CommandName="Edit" Text="Edit"></asp:LinkButton>
  </ItemTemplate>
  <EditItemTemplate>
    <asp:LinkButton id="LinkUpdate" runat="server"
CommandName="Update" Text="Update"></asp:LinkButton>
    <asp:LinkButton id="LinkCancel" runat="server"
CausesValidation=False CommandName="Cancel" Text="Cancel"></asp:LinkButton>
  </EditItemTemplate>
</asp:TemplateColumn>

So, we have Edit link visible in view mode and Update, Cancel links visible in edit mode. User can edit any fields by typing in TextBoxes, changing selected value in DropDownLists or changing value in CheckBoxes.
After that, user can hit Update link to accept changes to database or Cancel link to return to view mode without changing anything.
Developer must also add code to DataGrid.EditCommand Event handler such way:

Private Sub ProductsDataGrid_EditCommand(ByVal source As Object_
ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) _
Handles ProductsDataGrid.EditCommand
  ProductsDataGrid.EditItemIndex = e.Item.ItemIndex
  BindDataGrid()
End Sub
Generated using PrettyCode.Encoder

Validating user inputs

In some cases the user can enter incorrect values during editing. Validators prevent the user from doing that.
You can use as many validators as you want in different columns. But how to output errors in one single place? The answer is a ValidationSummary contol which displays messages from all validators in a single place. I used RequiredFieldValidator for ProductName and QuantityPerUnit fields and CompareValidator for UnitPrice, UnitsInStock, ReorderLevel field which checked that user input a correct type of a value.
Here is a screenshot of the “validation” on web form:

 

DataGrid updating

Ths now is the most complex part of coding. From the user's side, everything is easy but from the developer side it is not.
When the user hits Update link, the DataGrid raises the UpdateCommand Event. The event handler receives an argument of type DataGridCommandEventArgs containing data related to this event. The most helpful data is DataItem that represents the selected item in the DataGrid control. As I found from many forums, the main question is how to retrieve a data which the user has input? The solution is to use code like the following:

Dim ProductIDLabel As Label = _
CType(e.Item.Cells(0).FindControl("ProductIDLabel"), Label)


Dim ProductID As Integer = Int32.Parse(ProductIDLabel.Text)
Generated using PrettyCode.Encoder

When we collected all changed values, we can update the currect row in DataTable.

Deleting rows from DataGrid

Sometimes the user would like to remove rows from a DataGrid. No problem. But in my view the user should be asked to confirm before deleting a row. For that, I added a client script which prompts the user to confirm a delete action.

<script language="javascript">
<!--
function OnDeleteClick(id)
{
    if (window.confirm('Are you sure want to delete a product?'))
    { 
      document.all("DeleteProduct").value = id;
      __doPostBack("DeleteButton");
    }
}
//-->
</script>

Here is the code for column where Delete button placed:

<asp:TemplateColumn>
  <ItemStyle HorizontalAlign="Center" VerticalAlign="Middle"></ItemStyle>
  <ItemTemplate>
    <a href="javascript:OnDeleteClick('<%# DataBinder.Eval(Container, _
"DataItem.ProductID")%>');">Delete</a>
  </ItemTemplate>
</asp:TemplateColumn>

The following is a screenshot of the prompt message:

Summary

In this article we have taken a walk through some features of the web DataGrid control such as sorting, paging, editing, updating, deleting, etc. We have also written some code snippets to demonstrate how to implement DataGrid features. The source code (both VB.NET and C#) is attached.