2012-11-30 6 views
5

일부 응용 프로그램 코드를 System.DateTime 대신 NodaTime 클래스를 사용하도록 변환 중입니다. 내 응용 프로그램의 일부는 PropertyGrid 컨트롤을 사용하여 사용자가 LocalDate 및 Instant를 모두 포함하는 클래스를 편집 할 수있게합니다. 아무 것도 변경하지 않고 PropertyGrid가 속성을 표시하지만 더 이상 편집 할 수는 없습니다. 사용자가이 필드를 편집 할 수있는 가장 좋은 방법은 무엇입니까? 박람회를 위해서 PropertyGrid에서 NodaTime 클래스는 어떻게 사용합니까?

, 우리는 내가 표시하고 편집하고 싶은 물건의 유형의 대표로이 클래스를 사용할 수 있습니다

public class User 
{ 
    public string Name { get; set; } 
    public LocalDate BirthDate { get; set; } 
    public Instant NextAppointment { get; set; } 
} 

답변

4

내가 지금까지 함께 왔어요 최저 :

1 단계 : 노다 클래스를 편집 할 수 있습니다 것을

public class ToAndFromStringTypeConverter : TypeConverter 
{ 
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) 
    { 
     if (sourceType == typeof(string)) 
      return true; 
     else 
      return base.CanConvertFrom(context, sourceType); 
    } 
    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) 
    { 
     if (destinationType == typeof(string)) 
      return true; 
     else 
      return base.CanConvertTo(context, destinationType); 
    } 
} 

public class LocalDateTypeConverter : ToAndFromStringTypeConverter 
{ 
    public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) 
    { 
     if (value is string) 
     { 
      DateTime parsed; 
      if (!DateTime.TryParse((string)value, out parsed)) 
       throw new ArgumentException("Cannot convert '" + (string)value + "' to LocalDate."); 
      else 
       return new LocalDate(parsed.Year, parsed.Month, parsed.Day); 
     } 
     else 
     { 
      return base.ConvertFrom(context, culture, value); 
     } 
    } 

    public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) 
    { 
     if (destinationType == typeof(string)) 
     { 
      var tvalue = (LocalDate)value;     
      try 
      { 
       var x = tvalue.ToString("yyyy-MM-dd"); 
       return x; 
      } 
      catch (NullReferenceException) 
      { 
       return "1900-1-1"; 
      } 
      catch 
      { 
       throw new ArgumentException("Could not convert '" + value.ToString() + "' to LocalDate."); 
      }     
     } 
     else 
      return base.ConvertTo(context, culture, value, destinationType); 
    } 

public class InstantTypeConverter : ToAndFromStringTypeConverter 
{ 
    public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) 
    { 
     if (value is string) 
     { 
      try 
      { 
       DateTime parsed = DateTime.Parse((string)value); 
       LocalDateTime dt = LocalDateTime.FromDateTime(parsed); 
       Instant i = dt.InZoneLeniently(DateTimeZoneProviders.Default.GetSystemDefault()).ToInstant(); 
       return i; 
      } 
      catch 
      { 
       throw new ArgumentException("Cannot convert '" + (string)value + "' to Instant."); 
      } 
     } 
     else 
     { 
      return base.ConvertFrom(context, culture, value); 
     } 
    } 

    public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) 
    { 
     if (destinationType == typeof(string)) 
     { 
      try 
      { 
       Instant tvalue = (Instant)value; 
       LocalDateTime local = tvalue.InZone(DateTimeZoneProviders.Default.GetSystemDefault()).LocalDateTime; 
       string output = LocalDateTimePattern.CreateWithInvariantCulture("yyyy-MM-dd HH:mm:ss.FFFFFF").Format(local); 
       return output; 
      } 
      catch 
      { 
       throw new ArgumentException("Could not convert '" + value.ToString() + "' to LocalDate."); 
      }      
     } 
     else 
      return base.ConvertTo(context, culture, value, destinationType); 
    } 
} 

2 단계 있도록 TypeConverter가의의를 만듭니다 TypeConverters 등록

를 사용하여 사용자 정의 컬렉션 편집기이 적절한 속성에이 속성을 추가하여 등록 할 수 있습니다

public class NodaCollectionEditor : System.ComponentModel.Design.CollectionEditor 
{ 
    public NodaCollectionEditor(Type collection_type) : base(collection_type) { } 

    protected override object CreateInstance(Type itemType) 
    { 
     if (itemType == typeof(LocalDate)) 
      return LocalDateHelper.MinValue; 
     else 
      return base.CreateInstance(itemType); 
    } 
} 

목록 같은 것들을 처리하기 위해 : 3

TypeDescriptor.AddAttributes(typeof(LocalDate), new TypeConverterAttribute(typeof(LocalDateTypeConverter))); 
TypeDescriptor.AddAttributes(typeof(Instant), new TypeConverterAttribute(typeof(InstantTypeConverter))); 

단계 :

앱의 상단에이 코드를 넣어 :

[System.ComponentModel.Editor(typeof(NodaCollectionEditor),typeof(System.Drawing.Design.UITypeEditor))] 
관련 문제