如何编写类似自定义模板字段的 DataControlField
我正在使用 GridView 来显示数据,其中数据列之一的类型为 DateTimeOffset。为了显示日期和在用户时区的时间中,我将用户的时区首选项保存到他或她的个人资料中(属性值键“TimezoneOffset”),并且在格式化日期和时间时需要访问它。次。
如果我要使用 templatefield,那么我需要写:
<abbr class="datetimeoffset">
<%#
((DateTimeOffset)Eval("CreatedDate"))
.ToOffset(new TimeSpan(-((Int32)Profile.GetPropertyValue("TimezoneOffset"))
.ToRepresentativeInRange(-12, 24), 0, 0)).ToString("f") %>
</abbr>
这太复杂并且不可重用。
我尝试将 TimeSpan
属性添加到代码隐藏(至少将其移出数据绑定表达式),但显然视图代码隐藏的属性在 <% 中无法访问# ... %>
。
因此,我认为我需要编写一个自定义 DataControlField
来格式化日期和日期。用户所在时区的时间。
我一开始就说:
public class DateTimeOffsetField : DataControlField
{
private TimeSpan userOffsetTimeSpan;
protected override DataControlField CreateField()
{
return new DateTimeOffsetField();
}
protected override void CopyProperties(DataControlField newField)
{
base.CopyProperties(newField);
((DateTimeOffsetField)newField).userOffsetTimeSpan = userOffsetTimeSpan;
}
public override bool Initialize(bool sortingEnabled, System.Web.UI.Control control)
{
bool ret = base.Initialize(sortingEnabled, control);
int timezoneOffset = ((Int32)HttpContext.Current.Profile.GetPropertyValue("TimezoneOffset")).ToRepresentativeInRange(-12, 24);
userOffsetTimeSpan = new TimeSpan(-timezoneOffset, 0, 0);
return ret;
}
}
但现在我陷入困境了。如何输出 HTML <%# ((DateTimeOffset)Eval("CreatedDate")).ToOffset(userOffsetTimeSpan).ToString("f") %>< ;/abbr>
每个单元格?
编辑:我一直在阅读一篇标题为前沿的文章:自定义数据控制字段。到目前为止,我已经添加了:
public override void InitializeCell(DataControlFieldCell cell, DataControlCellType cellType, DataControlRowState rowState, int rowIndex)
{
base.InitializeCell(cell, cellType, rowState, rowIndex);
if (cellType == DataControlCellType.DataCell)
{
InitializeDataCell(cell, rowState, rowIndex);
}
}
protected virtual void InitializeDataCell(DataControlFieldCell cell, DataControlRowState rowState, int rowIndex)
{
System.Web.UI.Control control = cell;
if (control != null && Visible)
{
control.DataBinding += new EventHandler(OnBindingField);
}
}
protected virtual void OnBindingField(object sender, EventArgs e)
{
var target = (System.Web.UI.Control)sender;
if (target is TableCell)
{
TableCell tc = (TableCell)target;
}
}
但是虽然本文设置了 TableCell
实例的 Text
属性,但我想将部分视图渲染到表格单元格中。这可能吗?
I am using a GridView
to display data where one of the data columns has type DateTimeOffset
. In order to display dates & times in the user's timezone, I save the user's timezone preference to his or her profile (property value key "TimezoneOffset"), and need to access it when formatting dates & times.
If I were to use templatefield, then I would need to write:
<abbr class="datetimeoffset">
<%#
((DateTimeOffset)Eval("CreatedDate"))
.ToOffset(new TimeSpan(-((Int32)Profile.GetPropertyValue("TimezoneOffset"))
.ToRepresentativeInRange(-12, 24), 0, 0)).ToString("f") %>
</abbr>
which is too complicated and not reusable.
I tried adding a TimeSpan
property to the code-behind (to at least move that out of the data binding expression), but apparently properties of the view's code-behind are inaccessible within <%# ... %>
.
Therefore, I think that I need to write a custom DataControlField
to format dates & times in the user's timezone.
I have started with:
public class DateTimeOffsetField : DataControlField
{
private TimeSpan userOffsetTimeSpan;
protected override DataControlField CreateField()
{
return new DateTimeOffsetField();
}
protected override void CopyProperties(DataControlField newField)
{
base.CopyProperties(newField);
((DateTimeOffsetField)newField).userOffsetTimeSpan = userOffsetTimeSpan;
}
public override bool Initialize(bool sortingEnabled, System.Web.UI.Control control)
{
bool ret = base.Initialize(sortingEnabled, control);
int timezoneOffset = ((Int32)HttpContext.Current.Profile.GetPropertyValue("TimezoneOffset")).ToRepresentativeInRange(-12, 24);
userOffsetTimeSpan = new TimeSpan(-timezoneOffset, 0, 0);
return ret;
}
}
But now I am stuck. How do I output the HTML <abbr class="datetimeoffset"><%# ((DateTimeOffset)Eval("CreatedDate")).ToOffset(userOffsetTimeSpan).ToString("f") %></abbr>
for each cell?
EDIT: I have been reading an article titled Cutting Edge: Custom Data Control Fields. So far I have added:
public override void InitializeCell(DataControlFieldCell cell, DataControlCellType cellType, DataControlRowState rowState, int rowIndex)
{
base.InitializeCell(cell, cellType, rowState, rowIndex);
if (cellType == DataControlCellType.DataCell)
{
InitializeDataCell(cell, rowState, rowIndex);
}
}
protected virtual void InitializeDataCell(DataControlFieldCell cell, DataControlRowState rowState, int rowIndex)
{
System.Web.UI.Control control = cell;
if (control != null && Visible)
{
control.DataBinding += new EventHandler(OnBindingField);
}
}
protected virtual void OnBindingField(object sender, EventArgs e)
{
var target = (System.Web.UI.Control)sender;
if (target is TableCell)
{
TableCell tc = (TableCell)target;
}
}
but whereas the article sets the Text
property of the TableCell
instance, I would like to render a partial view into the table cell. Is that possible?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我想通了。这是我最终得到的结果:
TimeagoDateTimeOffset.cs
:I figured it out. Here is what I ended up with:
TimeagoDateTimeOffset.cs
: