在DataGridView中列格式时间跨度 [英] Format TimeSpan in DataGridView column

查看:149
本文介绍了在DataGridView中列格式时间跨度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我见过这些问题,但都涉及到不可在CellStyle格式值的方法。我只想显示小时和分钟部分(16:05);不是秒,以及(16时05分13秒)。我试图迫使秒值零,但仍然得到了类似16:05:00。短用杂牌组装电脑一样,提供一个字符串或日期时间(和只显示时/分部分)有没有什么办法,我可以得到的格式做我想做的。

I've seen these questions but both involve methods that aren't available in the CellStyle Format value. I only want to show the hours and minutes portion (16:05); not the seconds as well (16:05:13). I tried forcing the seconds value to zero but still got something like 16:05:00. Short of using a kludge like providing a string or a DateTime (and only showing the hour/minutes part) is there any way I can get the formatting to do what I want.

推荐答案

我刚刚发现这个自己。不幸的是,该解决方案是相当复杂。好消息是,它的作品。

I just discovered this myself. Unfortunately, the solution is pretty involved. The good news is that it works.

首先,你需要一个 ICustomFormatter 的实施与<$ C $交易C>时间跨度值。 NET框架不包括这样一种类型外的即用;我的猜测的,这是因为微软不想必须处理涉及格式化一个模棱两可时间跨度(例如,做HH ?意思是总小时数或仅小时部分​​),以及当这些含糊混淆开发商将出现支持问题随后猛攻

Firstly, you need an ICustomFormatter implementation that deals with TimeSpan values. The .NET framework does not include such a type out-of-the-box; I am guessing this is because Microsoft didn't want to have to deal with the ambiguity involved in formatting a TimeSpan (e.g., does "hh" mean total hours or only the hour component?) and the ensuing onslaught of support issues that would arise when these ambiguities confused developers.

这是确定的 - 只是实现自己的。下面是我写的使用基本上是一个示例类相同的自定义格式字符串为日期时间 (那些是适用的,反正)*:

That's OK -- just implement your own. Below is a sample class I wrote that uses basically the same custom format strings as DateTime (those that were applicable, anyway)*:

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的要用来显示你的时间跨度

We're not finished yet. With this type in place, you are equipped to assign a custom formatter to the column in your DataGridView that you want to use for displaying your TimeSpan values.

让我们说,列被称为时间;那么你可以这样做:

Let's say that column is called "Time"; then you would do this:

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



所以,现在你设置了吧?

So now you're set up, right?

那么,对于一些奇怪的原因,你还是不是的方式出现100%。为什么自定义格式不能在这一点上踢,我真的不能告诉你。但是,我们的几乎的完成。在最后一个步骤是处理 CellFormatting 事件让我们写来实际生效,这一新功能:

Well, for some odd reason, you're still not 100% of the way there. Why custom formatting can't kick in at this point, I honestly couldn't tell you. But we're almost done. The one final step is to handle the CellFormatting event to get this new functionality we've written to actually take effect:

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 属性。

At last, we're finished. Setting the DefaultCellStyle.Format property of the DataGridViewColumn you want formatted according to your custom rules should now work as expected.

<子> *所以,H/HH几个小时,M/mm代表分钟。等等。

这篇关于在DataGridView中列格式时间跨度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆