5

DataGridViewで TimeSpan をカスタマイズする方法について、DataGridView 列の Format TimeSpanに従って、IFormatProvider と ICustomFormatter がどのように機能するかを理解しようとしています。フォーマットに関係なく、常に「foo」を返す完全にカスタムのフォーマッタを作成しました。

私は Int で使用していますが、渡される値をチェックせず、 を返すだけなので、すべての型で機能するはずだと思います"foo"

class MyFormatter : IFormatProvider, ICustomFormatter
{
    public object GetFormat(Type formatType)
    {
        Console.WriteLine("GetFormat");
        return this;
    }

    public string Format(string format, object arg, IFormatProvider formatProvider)
    {
        Console.WriteLine("Format");
        return "foo";
    }
}

そして、私はそれをに渡していint.ToString()ます:

int number = 10;
Console.WriteLine(number.ToString(new MyFormatter()));

私が得ているものは次のとおりです。

GetFormat
10

私が得たいと思っていたのは次のとおりです。

GetFormat
フォーマット
ふー

編集: DateTime のカスタム IFormatProvider を作成して使用する方法を見つけましたか? そして、そこの答えは、 orDateTime.ToString()以外は何も受け入れないと言い、オブジェクトが実装されていても、これらのタイプでない場合、オブジェクトは拒否されます- https://stackoverflow.com/a/2382481/492336DateTimeFormatInfoCultureInfoICustomFormatter

ToString()だから私の質問は、メソッドのすべてのケースでそれが当てはまるのですか? それは DataGridView にも当てはまりますか? また、どのような場合に真のカスタム フォーマッタを渡すことができますか?

4

2 に答える 2

1

整数に対して ToString を呼び出して IFormatProvider を提供すると、大まかに次の方法でNumberFormatInfoを抽出しようとします。

public static NumberFormatInfo GetInstance(IFormatProvider formatProvider)
{
  CultureInfo cultureInfo = formatProvider as CultureInfo;
  if (cultureInfo != null && !cultureInfo.m_isInherited)
    return cultureInfo.numInfo ?? cultureInfo.NumberFormat;
  NumberFormatInfo numberFormatInfo = formatProvider as NumberFormatInfo;
  if (numberFormatInfo != null)
    return numberFormatInfo;
  if (formatProvider != null)
  {
    NumberFormatInfo format = formatProvider.GetFormat(typeof (NumberFormatInfo)) as NumberFormatInfo;
    if (format != null)
      return format;
  }
  return NumberFormatInfo.CurrentInfo;
}

したがって、他のすべてが失敗した場合は、とGetFormat等しい型で呼び出しNumberFormatInfo、期待NumberFormatInfoして戻ってくることがわかります。から返さないGetFormatため、代わりにデフォルトのフォーマッタを使用します (現在のカットルアー)。この場合、それを使用する有効な方法は次のようになります。

class MyFormatter : IFormatProvider, ICustomFormatter
{
    public object GetFormat(Type formatType)
    {
        if (formatType == typeof(NumberFormatInfo)) {
            return new NumberFormatInfo()
            {
                // something here
            };
        }
        Console.WriteLine("GetFormat");
        return this;
    }

    public string Format(string format, object arg, IFormatProvider formatProvider)
    {
        Console.WriteLine("Format");
        return "foo";
    }
}

しかし、この方法では、任意の数値に対して「foo」のような任意の値を返すことができるとは思えません。

于 2016-10-05T10:58:43.423 に答える
-2

実際に ToString() 関数は IFormatProvider を引数として受け入れ、その署名は次のように述べています。

ToString(IFormatProvider)
ToString(String)
ToString(String,IFormatProvider)

GetFormat(Type)IFormatProviderには実装する機能しかありません。機能を持っているものはToString()使用しません。したがって、の実装は次のとおりです。ICustomFormatterFormat()IFormatProvider

class MyFormatter : IFormatProvider
    {
        public object GetFormat(Type formatType)
        {
            Console.WriteLine("GetFormat");
            return this;
        }    
    }
于 2016-10-05T11:00:20.967 に答える