【问题标题】:How to write a custom templatefield-like DataControlField如何编写自定义模板字段,如 DataControlField
【发布时间】:2011-01-22 16:30:02
【问题描述】:

我使用GridView 来显示其中一个数据列的类型为DateTimeOffset 的数据。为了在用户的时区中显示日期和时间,我将用户的时区偏好保存到他或她的个人资料中(属性值键“TimezoneOffset”),并且在格式化日期和时间时需要访问它。

如果我要使用模板字段,那么我需要写:

<abbr class="datetimeoffset">
<%#
    ((DateTimeOffset)Eval("CreatedDate"))
    .ToOffset(new TimeSpan(-((Int32)Profile.GetPropertyValue("TimezoneOffset"))
                            .ToRepresentativeInRange(-12, 24), 0, 0)).ToString("f") %>
</abbr>

太复杂了,不能复用。

我尝试将TimeSpan 属性添加到代码隐藏(至少将其移出数据绑定表达式),但显然视图的代码隐藏属性在&lt;%# ... %&gt; 中无法访问。

因此,我认为我需要编写一个自定义 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 &lt;abbr class="datetimeoffset"&gt;&lt;%# ((DateTimeOffset)Eval("CreatedDate")).ToOffset(userOffsetTimeSpan).ToString("f") %&gt;&lt;/abbr&gt;

编辑:我一直在阅读一篇标题为 Cutting Edge: Custom Data Control Fields 的文章。到目前为止,我已经添加:

    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 属性,但我想将部分视图呈现到表格单元格中。这可能吗?

【问题讨论】:

    标签: c# asp.net data-binding templatefield


    【解决方案1】:

    我想通了。这是我最终得到的结果:

    // DateTimeOffsetField.cs
    public class DateTimeOffsetField : BoundField
    {
        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;
        }
    
        protected override void OnDataBindField(object sender, EventArgs e)
        {
            base.OnDataBindField(sender, e);
    
            var target = (Control)sender;
    
            if (target is TableCell)
            {
                var tc = (TableCell)target;
                var dataItem = DataBinder.GetDataItem(target.NamingContainer);
                var dateTimeOffset = (DateTimeOffset)DataBinder.GetPropertyValue(dataItem, DataField);
                tc.Controls.Add(new TimeagoDateTimeOffset { DateTimeOffset = dateTimeOffset.ToOffset(userOffsetTimeSpan) });
            }
        }
    }
    

    TimeagoDateTimeOffset.cs:

    [DefaultProperty("DateTimeOffset")]
    [ToolboxData("<{0}:TimeagoDateTimeOffset runat=server></{0}:TimeagoDateTimeOffset>")]
    public class TimeagoDateTimeOffset : WebControl
    {
        [Bindable(true)]
        [Category("Appearance")]
        [DefaultValue("")]
        [Localizable(true)]
        public DateTimeOffset DateTimeOffset
        {
            get { return (DateTimeOffset)ViewState["DateTimeOffset"]; }
            set { ViewState["DateTimeOffset"] = value; }
        }
    
        protected override void RenderContents(HtmlTextWriter writer)
        {
            writer.BeginRender();
            writer.AddAttribute(HtmlTextWriterAttribute.Class, "timeago", false);
            writer.AddAttribute(HtmlTextWriterAttribute.Title, DateTimeOffset.ToString("o"));
            writer.RenderBeginTag("abbr");
            writer.Write(DateTimeOffset.ToString("d"));
            writer.RenderEndTag();
            writer.EndRender();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-17
      • 1970-01-01
      • 2021-06-26
      • 1970-01-01
      • 1970-01-01
      • 2022-08-19
      • 2012-03-07
      • 1970-01-01
      相关资源
      最近更新 更多