How To Format Bytes in GridView Using ASP.NET (Custom asp:BoundField Server Control)

 

(AKA, how to not use templates to do a simple GridView Column Formatting)

 

This post is inspired by another post on did on GridView date formatting years ago.  It’s still very popular.

If you are like me, you don’t like using GridView Templates because it makes you write ugly verbose code.  In this post, I’ll show you how to do a quick customization of the BoundField asp.net  server control.  That is, the one you typically see in GridView as follows:

 

image

What we plan to do, is to create a custom control that looks like the following:

image

and will end up displaying data in a table that looks like the following:

image

So, one approach could be to simply convert the second column into a template with GridView and build a function to call that converts the column from numbers like 267030000 to 267.3 MB.  To do that, the code on the GridView will look like the following:

image

And, the code behind will be as follows:

 

namespace GridViewExtendedBoundField
{
public partial class WebForm2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{

}

protected string FormatToBytes(long bytes)
{
return FormatBytes(bytes);
}

public string FormatBytes(long bytes)
{
const int scale = 1024;
var orders = new string[] { "GB", "MB", "KB", "Bytes" };
var max = (long)Math.Pow(scale, orders.Length - 1);
foreach (string order in orders)
{
if (bytes > max)
return string.Format("{0:##.##} {1}", decimal.Divide(bytes, max), order);
max /= scale;
}
return "0 Bytes";
}
}
}
 
This is OK for a one time use, but if you plan on doing this kind of thing a lot, I think a better way to do it is to override the BoundField control with a custom server control.  Then, the code you write will look like the following and you will not need any code behind.
 
<%@ Register Assembly="CustomControls"  Namespace="BoundControls" TagPrefix="cc1" %>
...
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="Id,Bytes" DataSourceID="ObjectDataSource1">
<Columns>
<asp:BoundField DataField="Id" HeaderText="Id" ReadOnly="True"
SortExpression="Id" />
<cc1:BoundFieldBytesDisplay DataField="Bytes" FormatAsFancyBytes="true" >
</cc1:BoundFieldBytesDisplay>

The actual custom control you have to include is simply in library reference by the Assembly CustomControls (where you can put other stuff like this).  That code is as follows:

using System;
using System.Web.UI.WebControls;

namespace BoundControls
{
public class BoundFieldBytesDisplay : BoundField
{
public bool FormatAsFancyBytes
{
get
{
if (ViewState["FormatAsFancyBytes"] == null)
{
return false;
}
return (bool) ViewState["FormatAsFancyBytes"];
}
set { ViewState["FormatAsFancyBytes"] = value; }
}

protected override string FormatDataValue(object dataValue, bool encode)
{
if (!FormatAsFancyBytes)
{
return base.FormatDataValue(dataValue, encode);
}
else
{
return FormatBytes(Convert.ToInt64(dataValue));
}
}

/// <summary>
/// http://sharpertutorials.com/pretty-format-bytes-kb-mb-gb/
/// </summary>
/// <param name="bytes"></param>
/// <returns></returns>
public string FormatBytes(long bytes)
{
const int scale = 1024;
var orders = new[] {"GB", "MB", "KB", "Bytes"};
var max = (long) Math.Pow(scale, orders.Length - 1);
foreach (string order in orders)
{
if (bytes > max)
return string.Format("{0:##.##} {1}", decimal.Divide(bytes, max), order);
max /= scale;
}
return "0 Bytes";
}
}
}

That’s basically it!  Notice that in the custom control, all we have done is defined a property named “FormatAsFancyBytes” so we can set that to true.  Once that happens, we simply call the FormatBytes method and it does the job we expect. If we have “FormatAsFancyBytes” false, or left out, then this control will perform identically to a BoundField control because we are calling the base class.

Keep in mind, you can add all kinds of special properties now to this control to handle all sorts of formatting that might be common to your business.

Here is the sample project build with Visual Studio 2010 that demonstrates the above code.

Visual Studio 2010 Solution GridViewExtendedBoundField.zip

Visual Studio 2010 Solution GridViewExtendedBoundField.zip

About Peter Kellner

Peter is a software professional specializing in mobile and web technologies. He has also been a Microsoft MVP since 2007. In addition, he's a multi-course video author at Pluralsight. To read more about Peter Kellner and his experience click here. For information about how Peter Kellner might be able to help you with your project click here.

Follow me:


Comments

  1. Linux VPS Hosting says:

    Your blog is amazing! I can agree with almost everything you talk about!

Follow

Get every new post delivered to your Inbox

Join other followers: