I have a column in a datagridview that should convert to and only display integer values (ie. no decimal point). I have the DefaultCellStyle.Format set to "F0". I'm handling these format checks in the dgv_CellFormatting handler as shown.
private void dgv_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
// if it's first row or first column, display integer, no decimals
if ((e.ColumnIndex > 0 && e.RowIndex == 0) || (e.ColumnIndex == 0 && e.RowIndex > 0))
{
double tempVal = Double.Parse(e.Value.ToString());
string tempStr = System.Math.Round(tempVal).ToString("F0");
e.Value = tempStr;
}
}
I have initial values set for each cell in that column. If I leave the format as "F0", these initial values are displayed as integers (which is good). If I change format to "F1", it displays the values with one decimal place (adds .0). This makes sense.
However, when I have the format set to "F0", and click to edit the cell and enter "1.0" or "1.00", it doesn't correct the format back to "1". When the format is set to "F1" and I enter "5", it will correct it and properly display "5.0". But if I enter "5.00", it displays "5.00" and doesn't correct back to "5.0". It appears to only correct the format if a trailing zero addition is required, but not subtraction.
What's even stranger is that if I try to catch an entry of "x.00" with:
if (tempStr.EndsWith(".00")) tempStr.Substring(0, tempStr.Length-3);
it doesn't even catch the entry of "x.00", but then still displays "x.00" in the datagridview cell.
How do I enforce only integers with no decimals to be shown upon user entry?
Ugh found my issue (well two actually). In some other format checking code, I used a bad method to check to make sure the input is a number to avoid parsing non-number characters.
// don't format upper leftmost cell
// don't try to format a null or blank cell
// don't try to format unless it's a valid number
if (e.RowIndex < 0 || e.ColumnIndex < 0 || e.Value == null || e.Value == DBNull.Value ||
String.IsNullOrWhiteSpace(e.Value.ToString()) || !e.Value.ToString().All(char.IsDigit))
{
return;
}
The bad check is: e.Value.ToString().All(char.IsDigit). Well when I enter a number with a decimal point in the datagridview, the "." is not a number, therefore the function returns before formatting and applying the value.
The second issue is that 90% of the time, the number my hand flew to when testing was "1.0", expecting it to be formatted and displayed "1". Well, I set the entire table's NullValue to 1.0, and then modify the first row/col normal values as desired. When a user (me) enters "1.0", it is considered null and fails the if (e.Value == null) check. Therefore the formatting actions are skipped. Basically I confused "NullValue" property with initial cell value.
The Short Story
This code works:
double tempVal = Double.Parse(e.Value.ToString());
string tempStr = System.Math.Round(tempVal).ToString("F0");
e.Value = tempStr;