2016-10-05 4 views
1

DataGridView에서 TimeSpan을 사용자 정의하는 방법에 대해 Format TimeSpan in DataGridView column을 수행 한 후 IFormatProvider 및 ICustomFormatter가 작동하는 방식을 파악하려고합니다. 필자는 포맷팅에 관계없이 항상 "foo"를 반환하는 완전히 사용자 정의 된 포맷터를 만들었습니다.사용자 정의 포맷터를 구현하려고하지만 ICustomFormatter.Format은 호출되지 않습니다.

저는 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에도 적용 되는가? 그리고 어떤 경우에 진정한 맞춤형 포맷터를 전달할 수 있습니까? 당신이 정수에 ToString을 호출하는 IFormatProvider를 제공 할 때

+1

내가 그것을 도움이되지만'Console.WriteLine (및 String.format (새 MyFormatter()는, "{0}", 수)) 의심,'올바른 출력 – stuartd

답변

1

, 그것은 대략 다음과 같은 방법으로, 그것에서 를 추출하는 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에서 반환하지 않으므로 대신 기본 포맷터 (현재 cutlure)를 사용합니다. 이 경우에는 그것을 사용하는 그래서 유효한 방법이 될 것 같은 뭔가 :

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는"같은 임의의 값을 반환 할 수 있습니다 의심이 방법.

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

및 IFormatProvider를 단지 구현하는 GetFormat(Type) 기능을 가지고있다 :

+0

이 생성 불행히도 작동하지 않습니다 –

+0

어떤 의미에서 작동하지 않습니까? – Evk

+0

OP에서 표시된 예상 출력은 –

-1

사실 ToString() 함수는 서명을 말한다 인수로 IFormatProvider를받습니다. ToString()Format() 기능을 가진 ICustomFormatter을 사용하지 않습니다. 그래서 IFormatProvider의 구현은 다음과 같습니다

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