DataGridView custom formatting: parse edited value

1.1k Views Asked by At

Suppose I have a DataGridView that is bound to a BindingSource. The BindingSource has a DataSource of class MyClass

public class MyClass
{
    public double Percentage {get; set;}
    ...
}

The DataGridView shows the percentage as a double. So a value of 19% is displayed as 0.19, which is not what I want.

Luckily I can change the cell style of the column:

dataGridViewCellStyle.Format = "p";

This makes that the value is displayed as a percentage according to the current culture. In my culture 0.19 is displayed as 19%.

So far so good. But what happens if an operator changes this value to 18% and ends editing the cell.

  • Event CellValidating is raised. In this event I can check that the entered text is a perfect percentage.

However, immediately after that I get an exception that the string "18%" cannot be formatted to a double.

I guess I have to tell the datagridviewCellStyle which formatprivider to use:

datagridVieCellStyle.FormatProvider = new MyFormatProvider();

class MyFormatProvider : IFormatProvider
{
    public object GetFormat(Type formatType)
    {
        // what to return?
    }
}

Question Suppose I have the following class:

public static class PercentStringParser
{
     public static double Parse(string txt);
}

How should my format provider make that this function is called?

1

There are 1 best solutions below

0
Harald Coppoolse On BEST ANSWER

Do not use the format provider, but use event DataGridView.CellParsing.

private void OnCellParsing(object sender, DataGridViewCellParsingEventArgs e)
{
    if (e.ColumnIndex == this.percentageDataGridViewTextBoxColumn.Index
        && e.DesiredType == typeof(double)
        && ContainsPercentSign(e.Value.ToString()))
        {   // parsing a percentage to a double
            var formatProvider = this.dataGridView1.Rows[e.RowIndex]
                                     .Cells[e.ColumnIndex]
                                     .InheritedStyle
                                     .FormatProvider;

            try
            {
                e.Value = ParsePercentageToDouble(e.Value.ToString(), formatProvider);
                e.ParsingApplied = true;
            }
            catch (FormatException)
            {
                e.ParsingApplied = false;
            }
        }
        else
        {   // parsing any other column, let the system parse it
            e.ParsingApplied = false;
        }           
    }
}

MSDN example about this event