I was working on extending the DataControlField to display an icon based on an integer out of the database. There were four possible icons to display. In addition there was a requirement to show tool tip or not when hovering over the icon. This is controlled by values from the database. Here is the class code:
public class IconField : DataControlField {
private const string ONLINE_URL = “~/Images/online.gif”;
private const string OFFLINE_URL = “~/Images/offline.gif”;
private const string NOT_CHECKED_IN_URL = “~/Images/chk.gif”;
private const string CURRENT_LOGIN_URL = “~/Images/login.gif”;
private const string ONLINE = “Online”;
private const string OFFLINE = “Offline”;
private const string NOT_CHECKED_IN = “Not checked in”;
protected override DataControlField CreateField() {
return new IconField();
}
public override void InitializeCell(DataControlFieldCell cell, DataControlCellType cellType, DataControlRowState rowState, int rowIndex)
{
base.InitializeCell(cell, cellType, rowState, rowIndex);
if(cellType == DataControlCellType.DataCell) {
cell.DataBinding += new EventHandler(OnBindingField);
}
}
private void OnBindingField(object sender, EventArgs e) {
Control target = (Control)sender;
if(target is TableCell) {
object dataItem = DataBinder.GetDataItem(target.NamingContainer);
target.Controls.Add(createLiteralSpace(2));
target.Controls.Add(createIconDisplay((int)DataBinder.GetPropertyValue(dataItem, “Online”), (bool)DataBinder.GetPropertyValue(dataItem, “ShowToolTip”), (string)DataBinder.GetPropertyValue(dataItem, “CurrentLogin”)));
target.Controls.Add(createLiteralSpace(4));
}
}
private static Literal createLiteralSpace(int loops) {
Literal literal = new Literal();
for (int i = 0; i < loops; i++) {
literal.Text += “ ”;
}
return literal;
}
private static Image createIconDisplay(int online, bool showToolTip, string currentLogin) {
Image image = new Image();
image.ImageUrl = NOT_CHECKED_IN_URL;
switch (online) {
case 0:
image.ImageUrl = OFFLINE_URL;
break;
case 1:
if (currentLogin.Length > 0) {
image.ImageUrl = CURRENT_LOGIN_URL;
} else {
image.ImageUrl = ONLINE_URL;
}
break;
}
if (showToolTip) {
image.ToolTip = buildToolTip(online);
}
return image;
}
private static string buildToolTip(int online, string contactNotes) {
String toolTip = “”;
switch (online) {
case 0:
toolTip = OFFLINE;
break;
case 1:
toolTip = ONLINE;
break;
default:
toolTip = NOT_CHECKED_IN;
break;
}
return toolTip;
}
}
I override the InitializeCell method so I can wire up a new OnBindingField EventHandler. This will take the data from each row during the binding phase. To do this you use the DataBinder class. You grab the dataItem (the row from the GridView.DataSource) and use the DataBinder.GetPropertyValue. The second argument is the name of the property you want to get. These are class properties of the DataSource. Any GridView DataSource can be used: DataTable, IList, IEnumerable, etc.
To use this in any grid you first have to put this on the page:
<%@ Register TagPrefix=”MyTag” Assembly=”MyAssembly” Namespace=”MyNamespace” %>
Then in the grid <Columns> you refer to it with this:
<MyTag:IconField />
Easy enough, enjoy.