我试图弄清楚IFormatProvider和ICustomFormatter如何在Format TimeSpan in DataGridView column之后如何在DataGridView中自定义TimeSpan。我创建了一个完全自定义的格式化程序,无论格式化是什么,它总是返回“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 Format foo
修改:我找到了How to create and use a custom IFormatProvider for DateTime?,其中的答案是DateTime.ToString()
除了DateTimeFormatInfo
或CultureInfo
之外不会接受任何内容如果它不是这些类型,即使它实现ICustomFormatter
- https://stackoverflow.com/a/2382481/492336,也会被拒绝。
那么我的问题是在ToString()
方法的所有情况下都适用吗?它是否也适用于DataGridView,在哪些情况下我可以传递真正的自定义格式化程序?
答案 0 :(得分: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
的{{1}},并期望NumberFormatInfo
返回。您不会从NumberFormatInfo
返回它,因此它使用默认格式化程序(当前cutlure)。在这种情况下使用它的有效方法是:
GetFormat
但是这样我怀疑你可以为任何数字返回像“foo”这样的任意值。
答案 1 :(得分:-2)
实际上ToString()函数接受IFormatProvider作为其签名的参数:
ToString(IFormatProvider)
ToString(String)
ToString(String,IFormatProvider)
和IFormatProvider只有GetFormat(Type)
函数才能实现。 ToString()
不使用具有ICustomFormatter
功能的Format()
。所以
IFormatProvider
的实施是:
class MyFormatter : IFormatProvider
{
public object GetFormat(Type formatType)
{
Console.WriteLine("GetFormat");
return this;
}
}