2016-10-05 3 views
1

aufgerufen. Ich versuche herauszufinden, wie IFormatProvider und ICustomFormatter nach Format TimeSpan in DataGridView column zum Anpassen eines TimeSpan in einem DataGridView arbeiten. Ich habe einen vollständig benutzerdefinierten Formatierer erstellt, der unabhängig von der Formatierung immer "foo" zurückgibt.Versuchen Sie, ein benutzerdefiniertes Formatierungsprogramm zu implementieren, aber ICustomFormatter.Format wird nie

Ich benutze es auf Int, aber ich nehme an, es sollte auf alle Typen funktionieren, da es nicht überprüft, dass der Wert übergeben wird, es gibt nur "foo" zurück.

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"; 
    } 
} 

Und ich bin es vorbei an int.ToString():

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

Was ich bekomme ist:

GetFormat 
10

Während das, was ich hatte gehofft, zu bekommen:

GetFormat 
Format 
foo

Edit: Ich fand How to create and use a custom IFormatProvider for DateTime? und die Antworten dort sagen, dass DateTime.ToString() wird nichts akzeptieren, aber DateTimeFormatInfo oder CultureInfo und ein Objekt wird abgelehnt, wenn es nicht von diesen Typen ist, auch wenn es implementiert ICustomFormatter - https://stackoverflow.com/a/2382481/492336.

Also meine Frage ist dann, dass in allen Fällen der ToString() Methoden gilt? Gilt es auch für DataGridView und in welchen Fällen kann ich einen wirklich benutzerdefinierten Formatierer übergeben?

+1

Ich bezweifle, es hilft aber 'Console.WriteLine (string.Format (neu MyFormatter() "{0}", number));' erstellt die korrekte Ausgabe – stuartd

Antwort

1

Wenn Sie ToString auf integer anrufen und bieten IFormatProvider, wird es versuchen Number daraus zu extrahieren, etwa in der folgenden Art und Weise:

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; 
} 

Sie sehen also, wenn alles andere fehlschlägt, ruft GetFormat mit Geben Sie gleich NumberFormatInfo ein und erwartet NumberFormatInfo zurück. Sie geben es nicht von GetFormat zurück, so dass stattdessen der Standardformatierer verwendet wird (aktuelle Version). So gültig, wie es in diesem Fall zu verwenden, wäre so etwas wie sein:

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"; 
    } 
} 

Aber auf diese Weise ich bezweifle, dass Sie beliebige Werte wie „foo“ zurückgeben können für eine beliebige Anzahl.

+0

dieses funktioniert leider nicht –

+0

In welchem ​​Sinne funktioniert nicht? – Evk

+0

die angezeigte erwartete Ausgabe von OP kommt nicht –

-1

Eigentlich ToString() Funktion übernehmen IFormatProvider als Argument seine Unterschrift sagt:

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

und IFormatProvider hat nur GetFormat(Type) Funktion zu implementieren. ToString() verwendet nicht ICustomFormatter, die Format() Funktion hat. So die Implementierung für IFormatProvider ist:

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