LOGIN    REGISTER    YOUR CART

homepage
VisualHint's blog
May06

How to format a number with a specific CultureInfo/NumberFormatInfo in the PropertyGrid ?

“How to format a number in the PropertyGrid” is a question that I’m often asked. The following answer is valid for the MS PropertyGrid and for Smart PropertyGrid.Net. Therefore it is not in the SPG documentation.

The following explanation will be given for a Double number. You can easily apply it to a Single or a Decimal. If your target instance has a Double property, it uses by default the DoubleConverter TypeConverter. Unfortunately (for the present need) this converter uses the “R” format specifier when it converts from a double to a string in the ConvertTo method and the NumberStyles.Float style when it converts back a string to a double in the ConvertFrom method. “R” is called the round-trip format and it does not use the culture set for the application. It’s useful to ensure that a double converted to a string will result in the same original double when converted back.

It means that to solve our problem we must define a new TypeConverter and attach it to our Double property. We can derive it from DoubleConverter but we will override the ConvertTo and ConvertFrom methods. Here is the code of this converter:

public class MyConverter : DoubleConverter
{
    public override object ConvertTo(ITypeDescriptorContext context,
        CultureInfo culture, object value, Type destinationType)
    {
        if ((destinationType == typeof(string)) &&
            (value.GetType() == typeof(double)))
        {
            double num = (double)value;
            return num.ToString("N", culture.NumberFormat);
        }

        return base.ConvertTo(context, culture, value, destinationType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context,
        CultureInfo culture, object value)
    {
        if (value is string)
            return double.Parse(value as string, culture);

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

To set a specific culture usable by the PropertyGrid, you can change the global culture of the application. For example:

Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-us"); 

In SPG.Net you have also another option. You can set a CultureInfo instance per property. If you don’t, it will use the one of the application. This is useful for example to display numbers with various precisions or different currency formats.

protected override void OnPropertyCreated(PropertyCreatedEventArgs e)
{
    PropertyValue propertyValue = e.PropertyEnum.Property.Value;

    if ((propertyValue != null) && (propertyValue.UnderlyingType ==
        typeof(double)))
    {
        e.PropertyEnum.Property.Value.CultureInfo.NumberFormat.
            NumberDecimalDigits = 6;
    }

    base.OnPropertyCreated(e);
}