How do I format/Alter displayed value in property

2019-07-08 10:58发布

问题:

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 ?

回答1:

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