Search code examples
c#.netwinformspropertygridtypeconverter

How do I format/Alter displayed value in property grid


Am trying to work with a Winform Property Grid, and I am not able to format displayed value (mind too strongly tied to wpf now)

So what I want is, there is a drop down in property grid that has its own UITypeEditor, this editor shows values such as

1 - On
2 - Off
3 - Unknown

so the property on that listens to propertyGrid changes is int and for some odd reasons I cant change it to string, so like in wpf can I have a converter sort of thing that converts 1 into 1- On and 1-On to 1 ?

how can I decorate my property or property grid to be this intelligent ?

My property looks like

[LocalizedCategory("Limits", typeof(Api.Properties.Resources))]
[LocalizedDisplayName("Maximum", typeof(Api.Properties.Resources))]
[LocalizedDescription("Maximum", typeof(Api.Properties.Resources))]
[Editor(typeof(TextConversionTypeEditor), typeof(UITypeEditor))]
public int CriticalMaximum
{
    get; set;
}

Can I make my property grid display more information than just an int ?


Solution

  • If you can use an Enum as type of your property, then it shows available values in drop-down, otherwise you can create a TypeConverter to provide values for drop-down. To do so you can use either of these options:

    Use TypeConverter of an Enum for your int Property

    If values are limited and known at design-time, In this case although the property is int, you can use the converter of an Enum for your property, without overriding anything:

    public class MyObject
    {
        [TypeConverter(typeof(MyTypeConverter))]
        public int MyProperty { get; set; }
    }
    public class MyTypeConverter : EnumConverter
    {
        public MyTypeConverter() : base(typeof(MyValues)) { }
    }
    public enum MyValues
    {
        On = 1,
        Off,
        Unknown
    }
    

    Create your own TypeConverter which supports standard values

    If you can not have an enum and your standard values are generated at run-time, you can create such TypeConverter:

    public class MyTypeConverter : TypeConverter
    {
        Dictionary<int, string> values;
        public MyTypeConverter()
        {
            values = new Dictionary<int, string> { { 1, "1 - On" }, { 2, "2 - Off" }, { 3, "3 - Unknown" } };
        }
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            if (sourceType == typeof(string)) return true;
            return base.CanConvertFrom(context, sourceType);
        }
        public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {
            if (value != null && values.ContainsValue(value.ToString()))
                return values.Where(x => x.Value == value.ToString()).FirstOrDefault().Key;
            return base.ConvertFrom(context, culture, value);
        }
        public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
        {
            if (destinationType == typeof(string) && value != null && value.GetType() == typeof(int))
                return values[(int)value];
            return base.ConvertTo(context, culture, value, destinationType);
        }
        public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
        {
            return true;
        }
        public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
        {
            return new StandardValuesCollection(values.Keys);
        }
    }