You have to implement the feature to parse an input value.
TimeSpanFormatter can be used to convert a bound TimeSpan data to a formatted string for displaying. But it can't convert an input value to TimeSpan. You have to convert an input value in DataGridView.CellParsing event handler.
The following is the sample code to parse an input value.
DataGridView.CellParsing event handler
private void dataGridView1_CellParsing(object sender, DataGridViewCellParsingEventArgs e)
{
if (e.DesiredType == typeof(TimeSpan))
{
TimeSpanParser parser = new TimeSpanParser();
e.Value = parser.Parse(e.Value.ToString(), e.InheritedCellStyle.Format);
e.ParsingApplied = true;
}
}
TimeSpanParser class
public class TimeSpanParser
{
private Regex formatParser;
private List<TimeSpanPart> parts;
public TimeSpanParser()
{
this.formatParser = new Regex("d{1,2}|h{1,2}|m{1,2}|s{1,2}|f{1,7}", RegexOptions.Compiled);
this.parts = new List<TimeSpanPart>();
}
public TimeSpan Parse(string input, string format)
{
this.parts.Clear();
var pattern = this.formatParser.Replace(format, m => ReplaceFormat(m));
var match = Regex.Match(input, "^" + pattern + "$");
TimeSpan result = new TimeSpan();
for (int i = 1; i < match.Groups.Count; i++)
{
var value = Convert.ToDouble(match.Groups[i].Value);
switch (this.parts[i - 1])
{
case TimeSpanPart.Day:
result = result.Add(TimeSpan.FromDays(value));
break;
case TimeSpanPart.Hour:
result = result.Add(TimeSpan.FromHours(value));
break;
case TimeSpanPart.Minute:
result = result.Add(TimeSpan.FromMinutes(value));
break;
case TimeSpanPart.Second:
result = result.Add(TimeSpan.FromSeconds(value));
break;
case TimeSpanPart.Millisecond:
int digit = match.Groups[i].Value.Length;
value =value * Math.Pow(10, 3 - digit);
result = result.Add(TimeSpan.FromMilliseconds(value));
break;
}
}
return result;
}
private string ReplaceFormat(Match match)
{
switch (match.Value)
{
case "dd":
case "d":
this.parts.Add(TimeSpanPart.Day);
return "(\\d{1,2})";
case "hh":
case "h":
this.parts.Add(TimeSpanPart.Hour);
return "(\\d{1,2})";
case "mm":
case "m":
this.parts.Add(TimeSpanPart.Minute);
return "(\\d{1,2})";
case "ss":
case "s":
this.parts.Add(TimeSpanPart.Second);
return "(\\d{1,2})";
case "fffffff":
case "ffffff":
case "fffff":
case "ffff":
case "fff":
case "ff":
case "f":
this.parts.Add(TimeSpanPart.Millisecond);
return "(\\d{1,7})";
default:
return match.Value;
}
}
}
TimeSpanPart enum
public enum TimeSpanPart
{
Day,
Hour,
Minute,
Second,
Millisecond,
}