在 PropertyGrid 中为 int 属性 提供字符串

Provide string for int property in PropertyGrid

假设我有一个 class 和一个整数 属性,我想在 PropertyGrid 中显示它。现在,PropertyGrid 不应该简单地显示整数值,而是列表中的相应字符串值以及进一步的下拉列表,其中包含 属性.

的可能值(也作为字符串)

我知道我必须为此使用 TypeConverter,并且我过去曾为字符串属性这样做过。但我无法弄清楚如何做到这一点。从我的代码中可以看出,我完全无能为力:

class MyClassConverter : TypeConverter
{
    List<string> values = new List<string>(); 

    public MyClassConverter()
    {
        values.Add("Value1");
        values.Add("Value2");
        values.Add("Value3");
    }

    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        bool ret = true; //base.CanConvertFrom(context, sourceType);
        Debug.Print("CanConvertFrom: " + sourceType.ToString() + " " + ret.ToString());
        return ret;
    }

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        bool ret = base.CanConvertTo(context, destinationType);
        Debug.Print("CanConvertTo: " + destinationType.ToString() + " " + ret.ToString());
        return ret;
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        Debug.Print("ConvertFrom: " + value.GetType().ToString());
        //return base.ConvertFrom(context, culture, value);
        for (int i = 0; i < values.Count; i++)
        {
            if (values[i] == value)
            {
                return i;
            }
        }
        return -1;
    }

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        Debug.Print("ConvertTo: " + destinationType.ToString());
        return base.ConvertTo(context, culture, value, destinationType);
    }

    public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
    {
        Debug.Print("GetStandardValues");
        StandardValuesCollection collection = new StandardValuesCollection(values);
        return collection;
    }

    public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
    {
        return true;
    }
}

您必须使用 int 类型作为输入(以及隐式 string 类型作为输出,因为您正在与 属性 网格通信来实现 ConvertTo ).

此外,如果您想支持直接最终用户 int 输入,您还需要将 int 中的 ConvertFrom 实现为 string(如“2 ” 例如)。

这是一段似乎有效的代码:

public class MyClassConverter : TypeConverter
{
    private List<string> values = new List<string>();

    public MyClassConverter()
    {
        values.Add("Value1");
        values.Add("Value2");
        values.Add("Value3");
    }

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        if (value is int)
        {
            int index = (int)value;
            if (index >= 0 && index < values.Count)
                return values[index];

            return values[0]; // error, go back to first
        }
        return value;
    }

    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        string s = value as string;
        if (s != null)
        {
            int index = values.IndexOf(s);
            if (index >= 0)
                return index;

            // support direct integer input & validate
            if (int.TryParse(s, out index) && index >= 0 && index < values.Count)
                return index;

            return 0; // error, go back to first
        }

        return base.ConvertFrom(context, culture, value);
    }

    public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
    {
        return new StandardValuesCollection(values);
    }

    public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
    {
        return true;
    }
}