A bit overdue, but in case this helps someone, I solved this by firing up a decompiler (DotPeek) and analyzing what the base control was doing when calling InitializeDataCell
. It turns out, this method is protected
and is rather called in turn from the public
method InitializeCell
after some initialization. Additionally, it is responsible for subscribing the OnDataBindField
method to the DataBinding
event. Further inspection into OnDataBindField
revealed that this method is responsible setting the Text
property of the TableCell
, hence why, after postback, all I was left with was a string representation of the date.
I changed the Initialize method to InitializeCell
and overrode the OnDataBindField
(without calling its base counterpart) as follows:
public class TimeAgoBoundField : System.Web.UI.WebControls.BoundField
{
public override bool ReadOnly
{
get { return true; }
}
public override void InitializeCell(DataControlFieldCell cell, DataControlCellType cellType, DataControlRowState rowState, int rowIndex)
{
base.InitializeCell(cell, cellType, rowState, rowIndex);
if (cellType == DataControlCellType.DataCell)
{
cell.Controls.Add(new TimeAgoControl());
}
}
protected override void OnDataBindField(object sender, EventArgs e)
{
if (sender is TableCell)
{
var cell = (TableCell)sender;
var cellValue = this.GetValue(cell.NamingContainer);
if (cellValue != null)
{
var timeAgoControl = (TimeAgoControl) cell.Controls[0];
var dateTimeValue = (DateTime) cellValue;
var utcDateTime = dateTimeValue.Kind != DateTimeKind.Utc ? dateTimeValue.ToUniversalTime() : dateTimeValue;
timeAgoControl.ISO8601Timestamp = utcDateTime.ToString("s") + "Z";
}
else if (this.NullDisplayText != null)
{
cell.Text = this.NullDisplayText;
}
}
}
}
The msdn documentation for BoundField.OnDataBindField
now contains this note:
Notes to Inheritors When extending the BoundField class, you can override this method to perform a custom binding routine.