0

As a followup to this question on SO, I need help making a property grid interact with the user the way I want.

I have a property grid display formatted values as such

scr1

that come from class properties of type double

public interface IDisplayUnits 
{
    /// <summary>
    /// The current unit system
    /// </summary>
    UnitSystem Units { get; }
    bool UseRounding { get; set; }
    string Formatting { get; set; }
}

class TestUnits : IDisplayUnits
{
    public double A {get; set;}
    public double B {get; set;}
    public double C => A+B;
    public bool UseRounding { get; set; }
    public string Formatting { get; set; }
    public UnitSystem Units { get; set; }
}

public enum UnitSystem
{
    Metric,
    Inch
}

and implementing a custom TypeConverter that goes between double and string using the formatting I want.

Now what I want is, when the user edits a value to edit the raw (unformatted) value and not the rounded formatted value. For example when editing the A field to look like this

scr2

I have not been able to hook an event that triggers when the users starts to edit, or presses F4. The event PropertyValueChanged triggers after the edit.

It should be possible to do this, maybe by implementing a custom UITypeEditor?

Here is the current TypeConverter code that I have:

public class UnitValueConverter : TypeConverter
{
    // This checks if conversion is possible based on types only
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        if(sourceType == typeof(string))
        {
            return true;
        }
        return base.CanConvertFrom(context, sourceType);
    }
    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        if(destinationType == typeof(string))
        {
            return true;
        }
        return base.CanConvertTo(context, destinationType);
    }
    // This checks if conversion is possible based on specific values
    public bool CanConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value, out double result)
    {
        if(value is string input)
        {
            var parts = input.Split(' ');
            var has = context.Instance as IDisplayUnits;
            // Custom extension that parses a text like "10 mm"
            // into `x=10.0` and `sys = UnitSystem.Metric`
            if(input.TryParse(out double x, out UnitSystem sys))
            {              
                // irrelevent code for unit conversions      
                double f = Factor(sys, has.Units);
                result = f*x;
                return true;
            }
        }
        result = 0;
        return false;
    }
    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        if(CanConvertFrom(context, culture, value, out double result))
        {
            return result;
        }
        return base.ConvertFrom(context, culture, value);
    }
    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        if(destinationType==typeof(string))
        {
            double.TryParse(value.ToString(), out double x);

            if(context.Instance is IDisplayUnits has)
            {
                var f = has.UseRounding ? has.Formatting : "g";
                // irrelevent code for formatting values with units
                return Show(x, f);
            }
            return x.ToString("g");
        }
        return base.ConvertTo(context, culture, value, destinationType);
    }                
}

PS. I have seen commercial software out there that does exactly this.

John Alexiou
  • 28,472
  • 11
  • 77
  • 133
  • 1
    You can't hook events, you only have UITypeEditor and TypeConverter basically. UITypeEditor is only modal or dropdown, not inplace. But a TypeConverter should work, can you post your TypeConverter code (or one reproducing what does not work)? – Simon Mourier Jan 10 '18 at 16:35
  • @SimonMourier - Ok, I have edited the post showing more details. I the code is pretty standard boilerplate implementation of `TypeConverter` except that I check of the conversion is possible based on the input string. – John Alexiou Jan 10 '18 at 16:57
  • You can't change the value (the one displayed nor the underlying one) when the user enters the value cell to edit it. For example, look at what happens when you edit the Font property of a user control or a form, the value stays the same, ie: "Microsoft Sans Serif; 8,25pt" (and the converter is supposed to be able to parse it as is through (Can)ConvertFrom methods). You can add a UITypeEditor for a 100% custom editor, modal or dropdown (again, the Font property is an example of that). You could also create a custom "double" type – Simon Mourier Jan 15 '18 at 09:45

0 Answers0