Type 对象属性的 TypeConverter

leb*_*ero 3 c# typeconverter winforms

我需要在属性网格中正确显示对象。我的课程是这样的:

public class PropertyItem
{
    public PropertyDescription PropertyDescription { get; set; }

    [Description("the value"), Browsable(true)]
    public object Value { get; set; }

    public PropertyItem(PropertyDescription propertyDescription, object value)
    {
        PropertyDescription = propertyDescription;
        Value = value;
    }

    public override string ToString()
    {
        return this.PropertyDescription.Name + ": " + PropertyDescription.Type + ": " + Value;
    }
}
Run Code Online (Sandbox Code Playgroud)

Value是类型object,不能更改。ThePropertyDescription的类型为 the Value,这可以是任何内容 ( string, int, bool...)

当我设置SelectedObject我的时PropertyGridValue总是被禁用。

我该如何编写 aTypeConverter将 转换object ValueType中的PropertyDescription

Gyö*_*zeg 5

为属性定义自定义类型转换器:

[TypeConverter(typeof(PropertyValueConverter))]
public object Value { get; set; }
Run Code Online (Sandbox Code Playgroud)

并像这样实现它:

public class PropertyValueConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        var propItem = context.Instance as PropertyItem;
        return propItem != null && TypeDescriptor.GetConverter(propItem.PropertyDescription.Type).CanConvertFrom(context, sourceType)
            || base.CanConvertFrom(context, sourceType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        var propItem = context.Instance as PropertyItem;
        if (propItem != null)
            return TypeDescriptor.GetConverter(propItem.PropertyDescription.Type).ConvertFrom(context, culture, value);
        else
            return base.ConvertFrom(context, culture, value);
    }
}
Run Code Online (Sandbox Code Playgroud)

这个测试代码对我有用:

var pi = new PropertyItem(new PropertyDescription { Type = typeof(int) }, 1);
propertyGrid1.SelectedObject = pi;
Run Code Online (Sandbox Code Playgroud)

更新:

支持下拉列表(例如 bool):

    public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
    {
        var propItem = context.Instance as PropertyItem;
        if (propItem != null)
            return TypeDescriptor.GetConverter(propItem.PropertyDescription.Type).GetStandardValues(context);
        else
            return base.GetStandardValues(context);
    }

    public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
    {
        var propItem = context.Instance as PropertyItem;
        if (propItem != null)
            return TypeDescriptor.GetConverter(propItem.PropertyDescription.Type).GetStandardValuesSupported(context);
        else
            return base.GetStandardValuesSupported(context);
    }
Run Code Online (Sandbox Code Playgroud)

支持自定义可打开属性(例如点):

    public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
    {
        var propItem = context.Instance as PropertyItem;
        if (propItem != null)
            return TypeDescriptor.GetConverter(propItem.PropertyDescription.Type).GetProperties(context, value, attributes);
        else
            return base.GetProperties(context, value, attributes);
    }

    public override bool GetPropertiesSupported(ITypeDescriptorContext context)
    {
        var propItem = context.Instance as PropertyItem;
        if (propItem != null)
            return TypeDescriptor.GetConverter(propItem.PropertyDescription.Type).GetPropertiesSupported(context);
        return base.GetPropertiesSupported(context);
    }
Run Code Online (Sandbox Code Playgroud)