Consider the following facts:
- PropertyGrid uses TypeConverter of the property to get the string representation of the value.
- PropertyGrid uses a TextBox to to edit property values
- PropertyGrid has a SelectedGridItem property which tells you what is the selected property in the grid
Now the idea that I used, is:
- Register a custom TypeConverter for the double properties in your class, to show the formatted text for double values by default.
- Finding the editor TextBox and when Enter event happens, find the property using SelectedGridItem, and get the value and set the full value as text of the TextBox
Here is the implementation that worked for me:
using System.ComponentModel;
using System.Globalization;
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.propertyGrid1.SelectedObject = new Test();
//For .NET projects the field is _gridView
//For .NET Framework projects the field is gridView
var gridView = propertyGrid1.GetType()
.GetField("gridView",
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance)
.GetValue(propertyGrid1);
var edit = gridView.GetType()
.GetProperty("Edit",
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance)
.GetValue(gridView) as TextBox;
edit.Enter += (obj, args) =>
{
var name = propertyGrid1.SelectedGridItem.PropertyDescriptor?.Name;
if (name == "MyProperty1" || name == "MyProperty2")
{
edit.Text = propertyGrid1.SelectedGridItem.Value.ToString();
}
};
}
}
public class Test
{
[TypeConverter(typeof(MyDoubleConverter))]
public double MyProperty1 { get; set; } = 1.12345678;
[TypeConverter(typeof(MyDoubleConverter))]
public double MyProperty2 { get; set; } = 1.12345678;
}
public class MyDoubleConverter : DoubleConverter
{
public override object ConvertTo(ITypeDescriptorContext context,
CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(string) && value is double)
{
return ((double)value).ToString("N2");
}
return base.ConvertTo(context, culture, value, destinationType);
}
}