新文章 网摘 文章 随笔 日记

c# – 在DataGridView列中格式化TimeSpan

我见过 these questions,但都涉及CellStyle Format值中没有的方法.我只想显示小时和分钟部分(16:05);不是秒(16:05:13).我试图强制秒值为零,但仍然像16:05:00.如果没有使用像提供字符串或DateTime(并且仅显示小时/分钟部分)的kludge,那么我可以通过任何方式获得格式化以完成我想要的操作.
 
我自己就是发现了这个.不幸的是,解决方案非常复杂.好消息是它有效.

 

首先,您需要一个处理TimeSpan值的ICustomFormatter实现. .NET框架不包含这种开箱即用的类型;我猜这是因为微软不想处理格式化TimeSpan所涉及的歧义(例如,“hh”是指总小时还是仅小时组件?)以及随后可能出现的支持问题的冲击当这些含糊不清使开发人员感到困惑

没关系 – 只需实现自己的.下面是我写的一个示例类,它基本上使用了the same custom format strings as DateTime(那些适用的,无论如何)*:

 

class TimeSpanFormatter : IFormatProvider, ICustomFormatter
{
    private Regex _formatParser;

    public TimeSpanFormatter()
    {
        _formatParser = new Regex("d{1,2}|h{1,2}|m{1,2}|s{1,2}|f{1,7}", RegexOptions.Compiled);
    }

    #region IFormatProvider Members

    public object GetFormat(Type formatType)
    {
        if (typeof(ICustomFormatter).Equals(formatType))
        {
            return this;
        }

        return null;
    }

    #endregion

    #region ICustomFormatter Members

    public string Format(string format, object arg, IFormatProvider formatProvider)
    {
        if (arg is TimeSpan)
        {
            var timeSpan = (TimeSpan)arg;
            return _formatParser.Replace(format, GetMatchEvaluator(timeSpan));
        }
        else
        {
            var formattable = arg as IFormattable;
            if (formattable != null)
            {
                return formattable.ToString(format, formatProvider);
            }

            return arg != null ? arg.ToString() : string.Empty;
        }
    }

    #endregion

    private MatchEvaluator GetMatchEvaluator(TimeSpan timeSpan)
    {
        return m => EvaluateMatch(m, timeSpan);
    }

    private string EvaluateMatch(Match match, TimeSpan timeSpan)
    {
        switch (match.Value)
        {
            case "dd":
                return timeSpan.Days.ToString("00");
            case "d":
                return timeSpan.Days.ToString("0");
            case "hh":
                return timeSpan.Hours.ToString("00");
            case "h":
                return timeSpan.Hours.ToString("0");
            case "mm":
                return timeSpan.Minutes.ToString("00");
            case "m":
                return timeSpan.Minutes.ToString("0");
            case "ss":
                return timeSpan.Seconds.ToString("00");
            case "s":
                return timeSpan.Seconds.ToString("0");
            case "fffffff":
                return (timeSpan.Milliseconds * 10000).ToString("0000000");
            case "ffffff":
                return (timeSpan.Milliseconds * 1000).ToString("000000");
            case "fffff":
                return (timeSpan.Milliseconds * 100).ToString("00000");
            case "ffff":
                return (timeSpan.Milliseconds * 10).ToString("0000");
            case "fff":
                return (timeSpan.Milliseconds).ToString("000");
            case "ff":
                return (timeSpan.Milliseconds / 10).ToString("00");
            case "f":
                return (timeSpan.Milliseconds / 100).ToString("0");
            default:
                return match.Value;
        }
    }
}

我们还没完呢.有了这种类型,您就可以将自定义格式化程序分配给DataGridView中要用于显示TimeSpan值的列.

假设该列被称为“时间”;然后你会这样做:

 

DataGridViewColumn timeColumn = dataGridView.Columns["Time"];
timeColumn.DefaultCellStyle.FormatProvider = new TimeSpanFormatter();
timeColumn.DefaultCellStyle.Format = "hh:mm";

所以现在你已经成立了,对吧?

嗯,由于一些奇怪的原因,你仍然没有100%的方式.为什么自定义格式化不能在这一点上发挥作用,老实说我不能告诉你.但我们差不多完成了.最后一步是处理CellFormatting事件以获得我们编写的实际生效的新功能:

 

private void dataGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
    var formatter = e.CellStyle.FormatProvider as ICustomFormatter;
    if (formatter != null)
    {
        e.Value = formatter.Format(e.CellStyle.Format, e.Value, e.CellStyle.FormatProvider);
        e.FormattingApplied = true;
    }
}

最后,我们完成了.根据自定义规则设置要格式化的DataGridViewColumn的DefaultCellStyle.Format属性现在应该按预期工作.

*所以,“h”/“hh”表示小时,“m”/“mm”表示分钟.等等

http://www.voidcn.com/article/p-qhoxecbj-btn.html

posted @ 2021-04-18 11:04  岭南春  阅读(558)  评论(0)    收藏  举报