【问题标题】:How do you use NodaTime Classes in a PropertyGrid?如何在 PropertyGrid 中使用 NodaTime 类?
【发布时间】:2012-11-30 19:33:19
【问题描述】:

我正在转换一些应用程序代码以使用 NodaTime 类而不是 System.DateTime。我的应用程序的一部分使用 PropertyGrid 控件来允许用户编辑包含 LocalDate 和 Instant 的类。在不更改任何内容的情况下,PropertyGrid 可以正常显示属性,但它们不再可编辑。允许用户编辑这些字段的最佳方式是什么。

为了说明,我们可以用这个类来代表我想显示和编辑的东西的类型:

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

【问题讨论】:

    标签: c# .net propertygrid nodatime


    【解决方案1】:

    到目前为止我想出的最好的:

    第 1 步:创建 TypeConverter,以便 Noda 类可编辑

    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 步:注册 TypeConverters

    将此代码放在应用的顶部:

    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))]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-28
      • 1970-01-01
      • 2015-02-26
      相关资源
      最近更新 更多