Reputation: 81
I'm trying to write code in DataGridView
event CellFormatting
to trigger the logic that compares if column ( qty
and scanqty
) values in same row are different, then set background color to Yellow. But occur runtime error
System.ArgumentOutOfRangeException: 'Index was out of range. Must be non-negative and less than the size of the collection.'
Below is my sample code, anyone can help me, thank you very much.
private void dgProductList_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (this.dgProductList.Columns[e.ColumnIndex].Name == "scanqty")
{
var sqty = String.IsNullOrEmpty(e.Value.ToString()) ? 0 : int.Parse(e.Value.ToString());
var qty = int.Parse(dgProductList[e.RowIndex, 1].Value.ToString());
if (sqty != qty)
{
e.CellStyle.BackColor = Color.Yellow;
e.CellStyle.ForeColor = Color.Red;
}
else
{
e.CellStyle.BackColor = Color.White;
e.CellStyle.ForeColor = Color.Black;
}
}
}
Upvotes: 0
Views: 752
Reputation: 2042
As the other answers may be correct, I think the real problem here is that e.RowIndex
and e.ColumnIndex
can be -1 (e.g. for the header row). So you have to check if these indices are >= 0
first and ignore those with -1.
private void dgProductList_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (e.ColumnIndex >= 0 && this.dgProductList.Columns[e.ColumnIndex].Name == "scanqty")
{
// ...
}
}
Upvotes: 1
Reputation: 74690
Consider something like this, for performance reasons:
private void dgProductList_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (e.ColumnIndex == COL_INDEX_OF_SCANQTY_COLUMN)
{
var sqty = (DATATYPE_OF_SCANQTY)e.Value;
var qty = (DATATYPE_OF_QTY)dgProductList[1, e.RowIndex].Value;
if (sqty != qty)
{
e.CellStyle.BackColor = Color.Yellow;
e.CellStyle.ForeColor = Color.Red;
}
else
{
e.CellStyle.BackColor = Color.White;
e.CellStyle.ForeColor = Color.Black;
}
}
}
You don't need to round trip from string and back to int etc. Also you are happy to hard code that QTY is always column 1 but you look up the name of the column for scanqty and compare it to string to check if it's the scanqty column - you might as well hard code that too
If you don't know the datatypes of the values, pause it in the debugger and take a look..
Upvotes: 1
Reputation: 23732
when using the [ ]
operator to access data in the DataGridView
the syntax is :
dgProductList[columnIndex, rowIndex]
your are doing it the reverse way. please change this line:
var qty = int.Parse(dgProductList[e.RowIndex, 1].Value.ToString());
to this:
var qty = int.Parse(dgProductList[1, e.RowIndex].Value.ToString());
another possibility could be to use the column name qty
var qty = int.Parse(dgProductList["qty", e.RowIndex].Value.ToString());
Upvotes: 1