DataGridView validating old value insted of new value
I have a DataGridView that is bound to a DataTable, it has a column that is a double and the values need to be between 0 and 1. Here is my code
private void dgvImpRDP_InfinityRDPLogin_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
if (e.ColumnIndex == dtxtPercentageOfUsersAllowed.Index)
{
开发者_C百科 double percentage;
if(dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].Value.GetType() == typeof(double))
percentage = (double)dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].Value;
else if (!double.TryParse(dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].Value.ToString(), out percentage))
{
e.Cancel = true;
dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].ErrorText = "The value must be between 0 and 1";
return;
}
if (percentage < 0 || percentage > 1)
{
e.Cancel = true;
dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].ErrorText = "The value must be between 0 and 1";
}
}
}
However my issue when dgvImpRDP_InfinityRDPLogin_CellValidating
fires dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].Value
will contain the old value before the edit, not the new value.
For example lets say the old value was .1 and I enter 3. The above code runs when you exit the cell and dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].Value
will be .1 for that run, the code validates and writes 3 the data to the DataTable.
I click on it a second time, try to leave, and this time it behaves like it should, it raises the error icon for the cell and prevents me from leaving. I try to enter the correct value (say .7) but the the Value
will still be 3 and there is now no way out of the cell because it is locked due to the error and my validation code will never push the new value.
Any recommendations would be greatly appreciated.
EDIT -- New version of the code based off of Stuart's suggestion and mimicking the style the MSDN article uses. Still behaves the same.
private void dgvImpRDP_InfinityRDPLogin_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
if (e.ColumnIndex == dtxtPercentageOfUsersAllowed.Index)
{
dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].ErrorText = String.Empty;
double percentage;
if (!double.TryParse(dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].FormattedValue.ToString(), out percentage) || percentage < 0 || percentage > 1)
{
e.Cancel = true;
dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].ErrorText = "The value must be between 0 and 1";
return;
}
}
}
You need to use the FormattedValue property of the DataGridViewCellValidatingEventArgs instance instead of the cell value, as the cell value isn't updated until validation has succeeded:
The text entered by the user through the user interface (UI) becomes the FormattedValue property value. This is the value that you can validate before it is parsed into the cell Value property value. (MSDN)
How about doing something like this? This assumes you are using textbox's in your datagridview, so if you are using some other control, just change it to that. (Although I'm not sure why Stuart Dunkeld answer didnt work, FormattedValue should have the new value in it).
void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
if (e.ColumnIndex == 0) // dtxtPercentageOfUsersAllowed.Index
{
object should_be_new_value = e.FormattedValue;
double percentage;
if (dgvImpRDP_InfinityRDPLogin.EditingControl != null)
{
string text = dgvImpRDP_InfinityRDPLogin.EditingControl.Text;
if (!double.TryParse(text, out percentage))
{
e.Cancel = true;
dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].ErrorText = "The value must be between 0 and 1";
return;
}
if (percentage < 0 || percentage > 1)
{
e.Cancel = true;
dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].ErrorText = "The value must be between 0 and 1";
}
else
{
dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].ErrorText = null;
}
}
}
}
精彩评论