I have to admit – the GridView’s an extremely useful control that ships with Asp.net. This post covers several tasks you can accomplish in a GridView including:
- Sorting
- Paging
- Inserts
- Updates
- Deletes
Obviously, the techniques covered in this article aren’t the only way of accomplishing these tasks. There are several other approaches too but the one covered here served my purpose the best.
Before I start, I’d like to mention the obvious – A GridView is an improvement over .NET 1.x’s DataGrid. DataGrids, though extemely useful, still suffered some limitations. It required writing several lines of code repetitively to accomplish the same task. For example, binding data to a DataGrid required writing several lines of code. Asp.net 2.0 addressed issues like these through a set of data source controls “designed to encapsulate data that can be bound to data web controls.” A GridView was one such enchancement.
Ok let’s start.
Here’s a pretty simple GridView:
<asp:GridView CssClass=“GridView“ DataKeyNames=“ProductID“
ID=“GvProducts“ runat=“server“
AutoGenerateColumns=“False“ CellPadding=“0“ CellSpacing=“1“
ForeColor=“#333333“ GridLines=“None“ Width=“100%“
BorderWidth=“0px“ BorderStyle=“Solid“ BackColor=“White“
Font-Size=“15px“
OnRowEditing=“GvProductsEditCommand“
OnRowCancelingEdit=“GvProductsCancelCommand“
OnRowUpdating=“GvProductsUpdateCommand“
OnRowDeleting=“GvProductsOnDeleting“
AllowPaging=“True“
AllowSorting=“True“
OnPageIndexChanging=“GvProductsPageIndexChanging“
OnSorting=“GvProductsSortCommand“>
<HeaderStyle Font-Bold=“True“ ForeColor=“Black“
Font-Names=“Verdana“ Font-Size=“10px“
HorizontalAlign=“Center“ VerticalAlign=“Middle“
Wrap=“False“ Height=“25“ />
<FooterStyle ForeColor=“Black“></FooterStyle>
<Columns>
<asp:TemplateField ItemStyle-BorderWidth=“1px“ Visible=“False“ HeaderText=“ProductID“>
<ItemTemplate>
<asp:HiddenField ID=“HdProductID“ runat=“Product“ Visible=“False“ Value=‘<%# Eval(“ProductID“)%>‘ />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField ItemStyle-BorderWidth=“1px“ SortExpression=“ProductName“ HeaderText=“Product Name“>
<ItemTemplate>
<asp:Label ID=“LblProductName“ runat=“Product“ Visible=“true“ CssClass=“StandardText“ Text=‘<%# Eval(“ProductName“)%>‘ />
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID=“TxtProductName“ Enabled=“true“ Runat=“server“ Text=‘<%# Eval(“ProductName“)%>‘ />
</EditItemTemplate>
<ItemStyle Width=“18%“ HorizontalAlign=“center“ />
</asp:TemplateField>
<asp:TemplateField ItemStyle-BorderWidth=“1px“ SortExpression=“Cluster“ HeaderText=“Product Description“>
<ItemTemplate>
<asp:Label ID=“LblProductDescription“ runat=“server“ CssClass=“StandardText“ Text=‘<%# Eval(“ProductDescription“)%>‘ />
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID=“TxtProductDescription“ Enabled=“true“ Runat=“server“ Text=‘<%# Eval(“ProductDescription“)%>‘ />
</EditItemTemplate>
<ItemStyle Width=“18%“ HorizontalAlign=“center“ />
</asp:TemplateField>
<asp:CommandField HeaderText=“Action“ ShowDeleteButton=“true“ ItemStyle-BorderWidth=“1px“ ShowEditButton=“True“
DeleteText=“<img alt=’Save Changes’ src=’../../Images/delete.gif’ width=’15′ height=’15′ border=’0′>“
UpdateText=“<img alt=’Save Changes’ src=’../../Images/save.png’ width=’15′ height=’15′ border=’0′>“
CancelText=“<img alt=’Cancel Changes’ src=’../../Images/save_cancel.png’ width=’15′ height=’15′ border=’0′>“
EditText=“<img alt=’Edit’ src=’../../Images/edit.gif’ width=’15′ height=’15′ border=’0′>“>
<ItemStyle HorizontalAlign=“Center“ Width=“8%“ />
</asp:CommandField>
</Columns>
<RowStyle BackColor=“#ECECEC“ ForeColor=“#333333“ />
<SelectedRowStyle BackColor=“#FFCC66“ Font-Bold=“True“ ForeColor=“Black“ />
<PagerStyle BackColor=“#ececec“ ForeColor=“#333333“ HorizontalAlign=“Center“ />
<AlternatingRowStyle BackColor=“White“ />
</asp:GridView>
a
Here, I store two important variables in my page’s ViewState. They are:
- DsProducts – A DataSet that contains list of all my products.
- SortDirProducts – A boolean flag that holds the sort direction selected for my products (ASC or DESC).
a
/// <summary>
/// View State Variable
/// </summary>
public DataSet DsProducts {
get { return (DataSet)ViewState["DsProducts"]; }
set { this.ViewState["DsProducts"] = value; }
}
/// <summary>
/// Holds sort direction for GridView
/// </summary>
public bool SortDirProducts {
get { return (bool)ViewState["SortDirProducts"]; }
set { ViewState["SortDirProducts"] = value; }
}
a
DsProducts is initialized within the PageLoad function via the “DoDisplayProducts()” function. This function simply queries the database for a list of all existing products. This list is then bound to our GridView and is used to initialize our ViewState variable – DsProducts.
/// <summary>
/// Page load logic
/// </summary>
/// <param name=”sender”></param>
/// <param name=”e”></param>
protected void Page_Load(object sender, EventArgs e) {
if (!IsPostBack) {
//Display all products
DoDisplayProducts();
//Initialize Sort Direction
ViewState["SortDirProducts"] = true;
}
}
a
We also initialize the “SortDirProducts” variable within the PageLoad function.
/// <summary>
/// Displays servers available within the monitor app.
/// </summary>
protected void DoDisplayProducts()
{
//Initiate the Lookup Business Object
LookupBO LBO = new LookupBO();
try {
this.DsProducts = LBO.GetProducts();
if (this.DsProducts != null) {
if (this.DsProducts.Tables[0].Rows.Count > 0) {
this.GvProducts.DataSource = this.DsProducts;
this.GvProducts.DataBind();
this.GvProducts.Visible = true;
}
} else {
//Display Msg
this.LblResultServer.Text = “No Products Added.”;
this.LblResultServer.Visible = true;
}
} catch (Exception Ex) {
Console.WriteLine(Ex.ToString());
this.LblResultServer.Text = Ex.Message;
this.LblResultServer.Visible = true;
}
}
a
So far, we’ve got a list of products from the database, bound this list to our GridView and intialized our Sort Direction variable.
Next, lets go ahead and define our OnSorting event. This function is fired each time a user tries to sort data within a column. Also, it’s important to note, that a column will allow sorting only when a valid SortExpression is provided. In our GridView’s case, we’ve supplied the necessary dataset column names that allow sorting our data.
/// <summary>
/// Function fired when a column name is clicked within the GridView
/// This function sorts the GridView Based on the columns selected
/// </summary>
/// <param name=”sender”></param>
/// <param name=”e”></param>
protected void GvProductsSortCommand(object sender, GridViewSortEventArgs e) {
try {
//Set Sort Expression
ViewState["SortExpr"] = e.SortExpression;
//Retrieve DataView for DsProducts
DataView DvData = new DataView(this.DsProducts.Tables[0]);
//Based on value of the SortDirProducts View State value,
//Set the value of the SortDirStr varible to sort ASC (Ascending) or DESC (Descending)
string SortDirStr = “”;
if ((bool)ViewState["SortDirProducts"]) SortDirStr = ” ASC”;
else SortDirStr = ” DESC”;
//Sort DataView
DvData.Sort = (string)ViewState["SortExpr"] + ” “ + SortDirStr;
ViewState["SortDirProducts"] = !(bool)(ViewState["SortDirProducts"]);
//Bind GridView to sorted DataView
this.GvProducts.DataSource = DvData;
this.GvProducts.DataBind();
//Display GridView
this.GvProducts.Visible = true;
} catch (Exception Ex) {
Console.WriteLine(Ex.ToString());
this.LblResultServices.Text = Ex.Message;
this.LblResultServices.Visible = true;
}
}
a
Easy enough right? If you notice closely we toggle the value of our “SortDirProducts” variable between “ASC” and “DESC”. This allows the user to switch between ascending and descending sorts on a column. It’s also important to note, that we initialized the “AllowSorting” property of the our GridView to “true” as follows:
Next, let’s go ahead and define our PageIndexChanging functionality. First and foremost, it’s very important that we set a “PageSize” for our GridView and set the “AllowPaging” property of the GridView to “True”. Once this is done, we can handle our paging as follows:
/// Page index changing event
/// </summary>
/// <param name=”sender”></param>
/// <param name=”e”></param>
protected void GvProductsPageIndexChanging(object sender, GridViewPageEventArgs e) {
GvProducts.PageIndex = e.NewPageIndex;
GvProducts.DataSource = GetDataViewProducts();
GvProducts.DataBind();
}
/// <summary>
/// Create a View for the DataSet containing the servers
/// </summary>
protected DataView GetDataViewProducts() {
if (ViewState["SortExpr"] != null) {
//Toggle the Sort Direction each time the GerReportView method is called.
if (ViewState["SortDirProducts"] == null) {
ViewState["SortDirProducts"] = true;
}
//Based on value of the SortDirProducts View State value,
//Set the value of the SortDirStr varible to sort ASC (Ascending) or DESC (Descending)
string SortDirStr = “”;
if ((bool)ViewState["SortDirProducts"]) SortDirStr = ” ASC”;
else SortDirStr = ” DESC”;
GvDataViewProducts = new DataView(this.DsProducts.Tables[0]);
GvDataViewProducts.Sort = (string)ViewState["SortExpr"] + ” “ + SortDirStr;
ViewState["SortDirProducts"] = !(bool)(ViewState["SortDirProducts"]);
} else {
GvDataViewProducts = DsProducts.Tables[0].DefaultView;
}
return GvDataViewProducts;
}
a
This technique ensures that sorting (if any) is still intact when a user is paging through the results. Now, lets take a look at how we can insert, update and delete new items within our GridView.
/// <summary>
/// Function fired when editing an item within the GridView
/// </summary>
/// <param name=”sender”></param>
/// <param name=”e”></param>
protected void GvProductsEditCommand(object sender, GridViewEditEventArgs e) {
//Set Edit Index
this.GvProducts.EditIndex = e.NewEditIndex;
int ItemIndex = (GvProducts.PageIndex * GvProducts.PageSize) + e.NewEditIndex;
//Bind Gridview to DataSource
this.DoDisplayProducts();
try {
//Display Text Box in Edit Mode with “Product Name”
TextBox TxtProductName = (TextBox)GvProducts.Rows[this.GvProducts.EditIndex].FindControl(“TxtProductName”);
if (TxtProductName != null) {
string ProductName = this.DsProducts.Tables[0].Rows[ItemIndex]["ProductName"].ToString();
TxtProductName.Text = ProductName;
}
//Display Text Box in Edit Mode with “Product Name”
TextBox TxtProductDescription = (TextBox)GvProducts.Rows[this.GvProducts.EditIndex].FindControl(“TxtProductDescription”);
if (TxtProductDescription != null)
{
string ProductDescription = this.DsProducts.Tables[0].Rows[ItemIndex]["ProductDescription"].ToString();
TxtProductDescription.Text = ProductDescription;
}
} catch (Exception Ex) {
Console.WriteLine(Ex.ToString());
}
}
/// <summary>
/// Function fired when cancelling an edit command within the GridView
/// </summary>
/// <param name=”sender”></param>
/// <param name=”e”></param>
protected void GvProductsCancelCommand(object sender, GridViewCancelEditEventArgs e) {
try {
this.GvProducts.EditIndex = -1;
this.GvProducts.DataSource = this.DsProducts;
this.GvProducts.DataBind();
} catch (Exception Ex) {
Console.WriteLine(Ex.ToString());
}
}
/// <summary>
/// Function fired when updating an item within the GridView
/// </summary>
/// <param name=”sender”></param>
/// <param name=”e”></param>
protected void GvProductsUpdateCommand(object sender, GridViewUpdateEventArgs e) {
//Set Edit Index
this.GvProducts.EditIndex = e.RowIndex;
//Retrieve new server name
TextBox TxtProductName = (TextBox)this.GvProducts.Rows[e.RowIndex].FindControl(“TxtProductName”);
string ProductName = TxtProductName.Text;
//Retrieve new cluster name
TextBox TxtProductDescription = (TextBox)this.GvProducts.Rows[e.RowIndex].FindControl(“TxtProductDescription”);
string ProductDescription = TxtProductDescription.Text;
//Retrieve ProductID
HiddenField HdProductID = (HiddenField)this.GvProducts.Rows[e.RowIndex].FindControl(“HdProductID”);
int HdProductID = Convert.ToInt32(HdProductID.Value);
try {
AdminBO Bo = new AdminBO();
bool ReturnCode = Bo.UpdateProduct(HdProductID, ProductName, ProductDescription);
if (ReturnCode) {
this.LblResultProduct.Text = “Details for “ + ProductName + ” update successfully!.”;
this.LblResultProduct.Visible = true;
this.LblResultProduct.CssClass = “StandardTextGreen”;
this.GvProducts.EditIndex = -1;
this.DoDisplayProducts();
}
} catch (Exception Ex) {
this.LblResultProduct.Text = “Failed to update server details.”;
this.LblResultProduct.Visible = true;
this.LblResultProduct.CssClass = “StandardTextRed”;
Console.WriteLine(Ex.ToString());
}
}
/// <summary>
/// Function fired when deleting an item within the GridView
/// </summary>
/// <param name=”sender”></param>
/// <param name=”e”></param>
protected void GvProductsOnDeleting(object sender, GridViewDeleteEventArgs e) {
int HdProductID = Convert.ToInt32(this.GvProducts.DataKeys[e.RowIndex].Value);
try
{
AdminBO Bo = new AdminBO();
bool ReturnCode = Bo.DeleteProduct(HdProductID);
if (ReturnCode)
{
this.LblResults.Text = “Product Deleted Successfully.”;
this.LblResults.Visible = true;
this.LblResults.CssClass = “StandardTextGreen”;
this.GvProducts.EditIndex = -1;
this.DoDisplayProducts();
}
}
catch (Exception Ex)
{
this.LblResults.Text = “Failed to delete server.”;
this.LblResults.Visible = true;
this.LblResults.CssClass = “StandardTextRed”;
Console.WriteLine(Ex.ToString());
}
}
a
If you have any questions or want to download ths code, please leave me a comment. Once again, this I want to stress that I’m not claiming this technique of inserting, sorting, deleting etc. to be the best. It’s the one that matches my requirement the best.