我见过these questions,但都涉及CellStyle Format值中没有的方法。我只想显示小时和分钟部分(16:05);不是秒(16:05:13)。我试图强制秒值为零,但仍然像16:05:00。如果没有使用像提供字符串或DateTime(并且仅显示小时/分钟部分)的kludge,那么我可以通过任何方式获得格式化以实现我想要的效果。
答案 0 :(得分:11)
我自己就是发现了这个。不幸的是,解决方案非常复杂。好消息是它有效。
首先,您需要ICustomFormatter
实施来处理TimeSpan
值。 .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;
}
}
最后,我们结束了。根据您的自定义规则设置要格式化的DefaultCellStyle.Format
的{{1}}属性现在应该按预期工作。
*所以,“h”/“hh”表示小时,“m”/“mm”表示分钟。等子>
答案 1 :(得分:9)
仅使用CellFormatting事件就可以达到相同的效果。
private void dataGridView_CellFormatting(object sender,
DataGridViewCellFormattingEventArgs e)
{
if (e.Value != null && e.Value != DBNull.Value)
e.Value = ((TimeSpan)e.Value).Hours.ToString("00") + ":" +
((TimeSpan)e.Value).Minutes.ToString("00");
}
这显然不是一个全面的解决方案,但很快。
答案 2 :(得分:4)
尝试以下代码
dataGridView1.Columns["columnName"].DefaultCellStyle.Format = "hh\\:mm";
答案 3 :(得分:2)
我不知道如何设置单元格的格式以仅显示小时和分钟。我建议您将单元格的格式设置为字符串并格式化值,如下所示:
String.Format("{0:D2}:{1:D2}",
DateTime.Now.TimeOfDay.Hours, DateTime.Now.TimeOfDay.Minutes);
答案 4 :(得分:0)
尝试另一种方法。只需添加到您的类绑定到 datagridview 属性,例如 LastPacketAtTimeDelayAsStr
。
假设您有一些课程拥有它...
public DateTime? LastPacketAtTime { get; set; }
public TimeSpan? LastPacketAtTimeDelay
{
get
{
if (LastPacketAtTime.HasValue)
{
var ts = DateTime.Now - LastPacketAtTime.Value;
return ts;
}
return null;
}
}
public string LastPacketAtTimeDelayAsStr
{
get
{
if (LastPacketAtTimeDelay.HasValue)
{
var hours = LastPacketAtTimeDelay.Value.Hours.ToString("00");
var minutes = LastPacketAtTimeDelay.Value.Minutes.ToString("00");
var seconds = LastPacketAtTimeDelay.Value.Seconds.ToString("00");
return $"{LastPacketAtTimeDelay.Value.Days} days {hours}:{minutes}:{seconds}";
}
return null;
}
}
之后,只需将 LastPacketAtTimeDelayAsStr
绑定到您需要的 DataGridView
列,该列具有 String
数据类型。
就是这样!