От новичка до гуру: Курсы программирования на CyberDuff

Отформатируйте TimeSpan в столбце DataGridView

Я видел эти вопросы, но оба связаны с методами, которые недоступны в значении CellStyle Format. Я хочу показать только часы и минуты (16:05); не секунды (16:05:13). Я попытался установить значение секунд на ноль, но все равно получил что-то вроде 16:05:00. За исключением использования кладжа, такого как предоставление строки или DateTime (и показ только части часов / минут), есть ли способ получить форматирование, чтобы делать то, что я хочу.


Ответы:


1

Я только что сам это обнаружил. К сожалению, решение довольно сложное. Хорошая новость в том, что это работает.

Во-первых, вам нужна 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, который вы хотите отформатировать в соответствии с вашими пользовательскими правилами, теперь должна работать должным образом.

* Итак, «ч» / «чч» означает часы, «м» / «мм» - минуты. и т. д.

02.09.2010
  • Возможно, вы правы в том, почему этого нет во фреймворке. Это намного сложнее, чем я думал, спасибо. 02.09.2010
  • Прекрасно работает. Сердце чувствовало Спасибо. 11.11.2010
  • Здорово! У вас есть решение для обработки пользовательских правок с помощью этого настраиваемого средства форматирования? 09.06.2012
  • Начиная с .NET 4 вы можете (и должны) использовать решение @ David, см. msdn.microsoft.com/en-us/library/ee372287 (v ​​= vs.100) .aspx. 13.08.2014

  • 2

    Можно добиться того же эффекта, просто используя событие 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");
    }
    

    Это, очевидно, не такое комплексное решение, но довольно быстрое.

    15.11.2012
  • Начиная с .NET 4, это можно упростить до форматирования напрямую: 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

  • 3

    Попробуйте следующий код

    dataGridView1.Columns["columnName"].DefaultCellStyle.Format = "hh\\:mm";
    
    19.02.2015

    4

    Я не знаю, как настроить формат ячейки, чтобы отображались только часы и минуты. Я предлагаю вам установить формат ячейки как строку и отформатировать значение следующим образом:

    String.Format("{0:D2}:{1:D2}",
        DateTime.Now.TimeOfDay.Hours, DateTime.Now.TimeOfDay.Minutes);
    
    02.09.2010

    5

    Используйте строку формата "hh\\:mm". например

    YourGrid.Column[index].DefaultCellStyle.Format = "hh\\:mm"
    
    09.08.2017
  • Всегда проверяйте свое форматирование перед публикацией, чтобы убедиться, что все не потеряно из-за неправильного понимания Markdown. 09.08.2017

  • 6

    Попробуйте другой подход. Просто добавьте в свой класс привязку к свойствам 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.

    И это все!

    02.06.2021
    Новые материалы

    Я предполагаю, что вы имеете в виду методы обработки категориальных данных.
    Я предполагаю, что вы имеете в виду методы обработки категориальных данных. Пожалуйста, проверьте мой пост Инструментарий специалиста по данным для кодирования категориальных переменных в..

    Игра в прятки с данными
    Игра в прятки с данными Я хотел бы, чтобы вы сделали мне одолжение и ответили на следующие вопросы. Гуглить можно в любое время, здесь никто не забивается. Сколько регионов в Гане? А как..

    «Раскрытие математических рассуждений с помощью Microsoft MathPrompter и моделей больших языков»
    TL;DR: MathPrompter от Microsoft показывает, как использовать математические рассуждения с большими языковыми моделями; 4-этапный процесс для улучшения доверия и рассуждений в математических..

    Раскройте свой потенциал в области разработки мобильных приложений: Абсолютная бесплатная серия
    Глава 6: Работа в сети и выборка данных Глава 1: Введение в React Native Глава 2: Основы React Native Глава 3: Создание пользовательского интерфейса с помощью React Native Глава 4:..

    Все о кейсах: Camel, Snake, Kebab & Pascal
    В программировании вы сталкивались с ними при именовании переменной, класса или функции. Поддержание согласованности типов и стилей случаев делает ваш код более читабельным и облегчает совместную..

    Как работает дистанционное парное программирование и почему оно может изменить вашу жизнь
    Серебряная пуля от одиночества и отвлекающих факторов во время обучения программированию Независимо от того, работаете ли вы или учитесь удаленно, велика вероятность, что одиночество и..

    🔥🔥👉Питон 🆚Javascript👈🔥🔥
    Сегодня Python и Javascript потрясают мир в области ИТ. Все хотят выучить Python и Javascript, чтобы получить высокооплачиваемую работу. Различные фреймворки Python и Javascript расширяют..