Я видел эти вопросы, но оба связаны с методами, которые недоступны в значении CellStyle Format. Я хочу показать только часы и минуты (16:05); не секунды (16:05:13). Я попытался установить значение секунд на ноль, но все равно получил что-то вроде 16:05:00. За исключением использования кладжа, такого как предоставление строки или DateTime (и показ только части часов / минут), есть ли способ получить форматирование, чтобы делать то, что я хочу.
Отформатируйте TimeSpan в столбце DataGridView
Ответы:
Я только что сам это обнаружил. К сожалению, решение довольно сложное. Хорошая новость в том, что это работает.
Во-первых, вам нужна ICustomFormatter
реализация, которая работает со значениями TimeSpan
. Платформа .NET не включает такой тип "из коробки"; Я предполагаю, что это связано с тем, что Microsoft не хотела иметь дело с неоднозначностью, связанной с форматированием TimeSpan
(например, означает ли "чч" общее количество часов или только часовой компонент?) И вытекающие из этого натиск вопросов поддержки, которые могут возникнуть, когда эти двусмысленности сбивают разработчиков с толку.
Ничего страшного - просто реализуйте свое собственное. Ниже приведен пример класса, который я написал, который в основном использует те же строки настраиваемого формата, что и _4 _ (во всяком случае те, которые были применимы) *:
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
для DataGridViewColumn
, который вы хотите отформатировать в соответствии с вашими пользовательскими правилами, теперь должна работать должным образом.
* Итак, «ч» / «чч» означает часы, «м» / «мм» - минуты. и т. д.
Можно добиться того же эффекта, просто используя событие 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");
}
Это, очевидно, не такое комплексное решение, но довольно быстрое.
if( e.ColumnIndex == idx && e.Value != null && e.Value != DBNull.Value ) { e.Value = ((TimeSpan) e.Value).ToString( "ddd\\.hh\\:mm\\:ss" ); }
или даже лучше, добавив в инициализацию DataGridView следующее: dgv.Columns[ idx ].DefaultCellStyle.Format= "ddd\\.hh\\:mm\\:ss";
13.08.2014 Попробуйте следующий код
dataGridView1.Columns["columnName"].DefaultCellStyle.Format = "hh\\:mm";
Я не знаю, как настроить формат ячейки, чтобы отображались только часы и минуты. Я предлагаю вам установить формат ячейки как строку и отформатировать значение следующим образом:
String.Format("{0:D2}:{1:D2}",
DateTime.Now.TimeOfDay.Hours, DateTime.Now.TimeOfDay.Minutes);
Используйте строку формата "hh\\:mm"
. например
YourGrid.Column[index].DefaultCellStyle.Format = "hh\\:mm"
Попробуйте другой подход. Просто добавьте в свой класс привязку к свойствам 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
.
И это все!