Data Handling with a Shopping Cart/PayPal System
(Page 1 of 4 )
In this second of a three-part series exploring the GridView via a simple shop demo, we start by looking at one method of generating the GridView's DataSource and then proceed to use that data to create a fully functional shopping interface. The DataSource in this demonstration will be created on the fly.
A downloadable zip with the source and images is available here.
Introduction
I've used the DataGrid in almost every commercial C# .net project to date, so when I started hearing about the GridView and how it would take out a chunk of the work I kept doing I leaped at the chance to use it. Both the DataGrid and the GridView are classes that allow you to easily and quickly display tabular data. They both get rendered to HTML tables when viewed online.
This is the second article in a series exploring the GridView and demonstrating some of its usages via a simple shop demo. Each article is going to use the same source files which you can grab at the link shown above. To view the demo just unzip everything into a new directory on your web server and browse to the directory name. For example, if you unzipped it all into a directory called "gridviewshop" in the root of your web server you would navigate to:
http://www.yourserver.com/gridviewshop
If everything worked okay you should see a site that looks like this:

In the previous segment we covered what a GridView is and how it can be used, including how the actual data is bound to it. In this article we're going to look more closely at where that data comes from and how it can be used along with the GridView to implement a simple shop interface.
Where does the Data come from?
This really depends on what you're doing. It could come from a static XML file, a dynamic XML feed, a database, or maybe it's just created on the fly. It pretty much comes down to this: if there is data, you can be sure it can be pumped into a GridView. For this article the data is created on the fly each time the application is restarted.
The DataSource used to populate both GridViews is a DataTable. This is constructed using DataColumns and DataRows. Inside the main class file there is a function called "createProductDT." This shows how the DataTable is initially created. Here's the function in its entirety:
private DataTable createProductDT()
{
DataTable dtProducts = new DataTable();
DataColumn productColumn = new DataColumn();
productColumn.DataType = System.Type.GetType("System.Int32");
productColumn.ColumnName = "id";
productColumn.Unique = true;
dtProducts.Columns.Add(productColumn);
productColumn = new DataColumn();
productColumn.DataType = System.Type.GetType("System.String");
productColumn.ColumnName = "thumb";
dtProducts.Columns.Add(productColumn);
productColumn = new DataColumn();
productColumn.DataType = System.Type.GetType("System.String");
productColumn.ColumnName = "name";
dtProducts.Columns.Add(productColumn);
productColumn = new DataColumn();
productColumn.DataType = System.Type.GetType("System.Double");
productColumn.ColumnName = "price";
dtProducts.Columns.Add(productColumn);
productColumn = new DataColumn();
productColumn.DataType = System.Type.GetType("System.Int32");
productColumn.ColumnName = "quantity";
dtProducts.Columns.Add(productColumn);
// Make "id" the primary key
DataColumn[] pkColumns = new DataColumn[1];
pkColumns[0] = dtProducts.Columns["id"];
dtProducts.PrimaryKey = pkColumns;
return dtProducts;
}
First we create the DataTable object and then a DataColumn. For most columns we just set the DataType and the column name, although for the first column, "id," we also set it to be Unique. That's because we want this to be our primary key, which also requires a little addition near the end of the function to configure this. The reason we want the id to always be unique is that we'll be using this to reference the various products we will add to the DataSource later on, so we can pull specific data out, such as just that product's price and just that product's name. This function will return an empty DataTable and is only used in a couple of places, namely getBasket() and populateProducts().
We start adding actual rows to the DataSource within populateProducts(). This is shown below. Each row is a different product. Adding a new row to a DataTable requires you to create a new DataRow and then call the DataTable's NewRow() function. This will make room in the DataTable for the new row, but it will not actually add the row.
private void populateProducts()
{
// Create the basic structure
DataTable dtProducts = createProductDT();
// Add the products to it
// Create the initial row
DataRow aProduct = dtProducts.NewRow();
aProduct["id"] = 11;
aProduct["thumb"] = "images/widget0.jpg";
aProduct["name"] = "Red Widget";
aProduct["price"] = 19.99;
dtProducts.Rows.Add(aProduct);
// Re-use the row to add a new product
aProduct = dtProducts.NewRow();
aProduct["id"] = 22;
aProduct["thumb"] = "images/widget1.jpg";
aProduct["name"] = "Green Widget";
aProduct["price"] = 50.99;
dtProducts.Rows.Add(aProduct);
// Bind the DataTable to the Products GridView
gvProducts.DataSource = dtProducts;
gvProducts.DataBind();
// Store the products in Session
Session["dtProducts"] = dtProducts;
}
First we need to add some data to the row such as the id, thumbnail image path, name and price. Once those have been added we call the Add() function to actually add our new row to the DataTable. In the demo we add six products, although in the snippet above we just add two. You can see where I cheated and just reused the same column and the same row. Once this is done we bind the DataTable to our GridView with:
gvProducts.DataSource = dtProducts;
gvProducts.DataBind();
Remember the RowDataBound event we talked about earlier in the first article? Well once we call DataBind(), that function gets fired off and our data starts getting created on the page. You should be aware that under the hood there might be other things happening between these two events, but for the sake of clarity it's easier to just think of it this way.
After that we also store a copy of the DataTable in Session state so we can retrieve it later on instead of having to recreate it each time we want access to the product data. It should be noted that, while this is fine for a small amount of data on a small scale project, you shouldn't really do this for large scale applications as using the Session state eats away at your server's memory, so even using just a small amount of data can use tremendous amounts of memory if there are several thousand users accessing it simultaneously. You'll see the data being pulled out of the Session several times in this demonstration, but in reality you'd probably be performing numerous database calls to pull a more specific subset of data as and when it is needed.
One thing to note is that you can set "DataKeyNames." These can be used to index items in the GridView. The product listing and the basket each implement a single DataKeyName:
DataKeyNames="id"
This is then used later on when the "Add to basket" button is clicked to identify which product we want to add. In the basket it's used when the quantities are getting updated. You can have multiple key names, although a lot of the time you will only ever need one.
Before populating the GridView you can bind an empty DataTable to it. This will force it to show an empty row that you can pre-populate with a string. This is done with both GridViews in the demo, although the only one you'll ever really see is the baskets since it wouldn't make much sense to have no products in your shop. You set it using the "EmptyDataText" GridView property like this:
EmptyDataText="~Basket is empty~"
which then gets rendered on its own like this:

Next: The Shopping Basket >>
More C# Articles
More By Tann San