2012-11-30 13 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:登録TypeConverters

:野田クラスは

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年代を作成します。

アプリの上部にこのコードを入れてください:

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

ステップ3:これは、任意の適切なプロパティにこの属性を追加することで登録できるリスト

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

のようなものを処理するために使用したカスタムコレクションエディタを:

[System.ComponentModel.Editor(typeof(NodaCollectionEditor),typeof(System.Drawing.Design.UITypeEditor))] 
関連する問題