Formatting GridView output based on Data

Waqas Anwar
04 June 2009
28078 Views

ASP.NET GridView control is the most commonly used control for displaying data on the web page. If you want to display database records as HTML table “as is”, it is very easy to accomplish using GridView. Sometimes you want to customize the HTML output of the GridView and want to display data differently based on its value. In this tutorial I will show you how you can call custom formatting functions inside GridView to customize GridView control.

To give you clear idea what I am going to do in this tutorial I am showing you the GridView control below with no custom formatting applied on it. Notice how GridView displays Nullvalues in UnitPrice columns as empty cell and how it displays Boolean field OnSale as Checkbox controls.

GridView without Formatting
GridView Control without Formatting

Now I am showing you the same GridView control after custom formatting applied on it. Notice how it displays Null values in UnitPrice column, how it displays UnitsInStock value if it is 0, how it displays OnSale column both as string label (Yes/No) or happy or sad icons. I also added one extra column in which I am showing whether delivery of such item is Free or not based on its price.

GridView with Formatting
GridView Control with Formatting


To start this tutorial I have added one GridView control on page. Following code shows the HTML source of GridView control.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" BackColor="White"
            BorderColor="#336699" BorderStyle="Solid" BorderWidth="1px" CellPadding="2"
            Font-Names="Verdana" Font-Size="10pt" Width="60%" DataKeyNames="ProductID"
            GridLines="Horizontal">
  
   <Columns>
      <asp:BoundField DataField="ProductID" HeaderText="ProductID" />
      <asp:BoundField DataField="ProductName" HeaderText="ProductName" />
                              
      <asp:TemplateField HeaderText="UnitPrice">
         <ItemTemplate>
            <%# FormatUnitPrice(Eval("UnitPrice"))%>
         </ItemTemplate>
         <HeaderStyle HorizontalAlign="Center" />
         <ItemStyle HorizontalAlign="Center" />
      </asp:TemplateField>
              
      <asp:TemplateField HeaderText="Delivery">
         <ItemTemplate>
            <%# FormatDelivery(Eval("UnitPrice"))%>
         </ItemTemplate>
         <HeaderStyle HorizontalAlign="Center" />
         <ItemStyle HorizontalAlign="Center" />
      </asp:TemplateField>
              
      <asp:TemplateField HeaderText="UnitsInStock">
         <ItemTemplate>
            <%# FormatUnitsInStock(Eval("UnitsInStock")) %>
         </ItemTemplate>
         <HeaderStyle HorizontalAlign="Center" />
         <ItemStyle HorizontalAlign="Center" />
      </asp:TemplateField>
             
      <asp:TemplateField HeaderText="OnSale">
         <ItemTemplate>
            <%# FormatOnSaleLabel(Eval("OnSale"))%>                      
         </ItemTemplate>
         <HeaderStyle HorizontalAlign="Center" />
         <ItemStyle HorizontalAlign="Center" />
      </asp:TemplateField>
             
      <asp:TemplateField>
         <ItemTemplate>
            <asp:Image runat="server" ID="imgOnSale" ImageAlign="AbsMiddle"
               ImageUrl='<%# FormatOnSale(Eval("OnSale"))%>' />
         </ItemTemplate>
         <HeaderStyle HorizontalAlign="Center" />
         <ItemStyle HorizontalAlign="Center" />
      </asp:TemplateField>
              
   </Columns>
   <HeaderStyle BackColor="#336699" Font-Bold="True" ForeColor="White" HorizontalAlign="Left" />
</asp:GridView>

In the code above, I added several TemplateField columns in GridView and in those columns I called custom functions inside ASP.NET binding expressions as follows:
<%# FormatUnitPrice(Eval("UnitPrice"))%>
You can read any type of data using ASP.NET binding expression syntax <%#   %> and Eval() method and can pass values to these custom functions for custom formatting. These custom functions can have any type of custom formatting logic inside them and they are all supposed to return data as string. It can be a path of an image icon or video file or any thing else you want to render inside cell.

Inside code behind file I am first binding the data with GridView in the Page_Load event as shown below:
protected void Page_Load(object sender, EventArgs e)
{
   if (!Page.IsPostBack)
   {
      BindData();
   }
}

private void BindData()
{
   string constr = "Server=TestServer;Database=TestDatabase;uid=sa;pwd=sql;";
   string query = "SELECT ProductID, ProductName, UnitPrice, UnitsInStock, OnSale FROM Products";

   SqlDataAdapter da = new SqlDataAdapter(query, constr);
   DataTable table = new DataTable();

   da.Fill(table);
  
   GridView1.DataSource = table;
   GridView1.DataBind();
}

The first custom function is FormatUnitPrice which checks whether the value is Null using DBNull.Value property and if it is null it returns formatted “Not Set” string. If the price value is not Null it checks if the value is 0 and if it is not it sends actual price to the cell.
public string FormatUnitPrice(object objPrice)
{

   if (objPrice.Equals(DBNull.Value))
   {
      return "<span style='color: red; font-weight: bold;'>Not Set</span>";
   }
   else
   {
      decimal price = Convert.ToDecimal(objPrice);
      if (price <= 0)
      {
         return "<span style='color: red; font-weight: bold;'>Not Set</span>";
      }
      else
      {
         return price.ToString();
      }
   }
}

Second custom function is FormatDelivery performs similar functionality as the FormatUnitPrice as it also checks price but it also implements one business logic that is if price is above 1000 it displays string Free otherwise it displays Not Free.
public string FormatDelivery(object objPrice)
{
   if (objPrice.Equals(DBNull.Value))
   {
      return "";
   }
   else
   {
      decimal price = Convert.ToDecimal(objPrice);
      if (price <= 0)
      {
         return "";
      }
      else if (price >= 1000)
      {
         return "<span style='color: green; font-weight: bold;'>FREE</span>";
      }
      else
      {
         return "<span style='color: red; font-weight: bold;'>NOT FREE</span>";
      }
   }
}

Following is the code of third custom function FormatUnitsInStock which is similar to the above two methods. It checks whether stock is 0 or Null and then display strings accordingly.
public string FormatUnitsInStock(object objStock)
{
   if (objStock.Equals(DBNull.Value))
   {
      return "<span style='color: red; font-weight: bold;'>Out of Stock</span>";
   }
   else
   {
      int stock = Convert.ToInt32(objStock);
      if (stock <= 0)
      {
         return "<span style='color: red; font-weight: bold;'>Out of Stock</span>";
      }
      else
      {
         return stock.ToString();
      }
   }
}

Last two methods are formatting Boolean field OnSale and displaying either string or icons based on data value passed inside functions.
public string FormatOnSaleLabel(object objOnSale)
{
   bool onSale = Convert.ToBoolean(objOnSale);
   if (onSale)
   {
      return "Yes";
   }
   else
   {
      return "No";
   }
}

public string FormatOnSale(object objOnSale)
{
   string happyIcon = "~/images/happy.gif";
   string sadIcon = "~/images/sad.gif";

   bool onSale = Convert.ToBoolean(objOnSale);
   if (onSale)
   {
      return happyIcon;
   }
   else
   {
      return sadIcon;
   }
}

The technique of calling custom functions is very easy to implement and it gives you lot of flexibility because you can perform all types of business logic checks and calculations inside your functions and can display almost anything inside GridView control cells. I hope now you have clear idea how to format data differently inside GridView control.