Kate Mid Kate Mid - 1 month ago 21
C# Question

Compare value between 2 datagridview c#

I have 2 datagridviews.

dataGridView1
has 3 rows and
dataGridView2
has 2 rows.How to compare the values between them.

Exa: Datagridview1 Datagridview2
Id name Id name
1 A 3 C
2 B 4 A
3 C


I want to compare:


1 vs 3, 1 vs 4,

2 vs 3, 2 vs 4,

3 vs 3, 3 vs 4.


I use the code below but it works incorrect.

for (int i = 0; i < dataGridView1.RowCount; i++)
{
for (int j = 0; j < dataGridView2.RowCount; j++)
{
i++;
string grid2 = dataGridView2.Rows[j].Cells[1].Value.ToString();
string grid1 = dataGridView1.Rows[i].Cells[1].Value.ToString();
if (grid1 == grid2 || dataGridView2.Rows[0].Cells[1].Value.ToString() == dataGridView1.Rows[0].Cells[1].Value.ToString() )
{
dataGridView1.Rows.RemoveAt(i);
}
}
}

Answer Source

1)

If you want to iterate through a collection using a for loop it is not wise to increment the indexing variable additionally in the code with this line:

i++;

it is already incremented. So when you run through the dataGridView2 you actually slide one position further also in dataGridView1. This is not what you want (as I see from your post where you describe the desired comparisons). You need to remove this line

2)

I want to compare: 1 vs 3, 1 vs 4, 2 vs 3, 2 vs 4, 3 vs 3, 3 vs 4.

if you want to compare only the name column then your indexing is right :

dataGridView2.Rows[j].Cells[1]

but if you want to compare the Id column then it is wrong because indexing starts with 0. So to get the correct value from the Id column you have to use it like this:

string grid2 = dataGridView2.Rows[j].Cells[0].Value.ToString();

With this comparison in your if-condition:

 dataGridView2.Rows[0].Cells[1].Value.ToString() == dataGridView1.Rows[0].Cells[1].Value.ToString()

you additionally compare A with C. I don't see any reason for this (taken your description about the comparison desire). You can get rid of it.

3)

If you want to change the size of a collection (by deleting elements) through which you iterate it is wise to use a reversed for-loop which starts from the dataGridView2.RowCount-1 and runs until >= 0. Otherwise you risk to run into an ArgumentOutOfBounds exception because you don't have as much elements after removal as you did when you started the loop. The element at the end index will not exist anymore.

for (int i = dataGridView1.RowCount-1; i >= 0 ; i--)
{
    for (int j = 0; j < dataGridView2.RowCount; j++)
    {   
        string grid2 = dataGridView2.Rows[j].Cells[0].Value.ToString();
        string grid1 = dataGridView1.Rows[i].Cells[0].Value.ToString();
        if (grid1 == grid2)
        {
            dataGridView1.Rows.RemoveAt(i);
        }
    }
}

EDIT:

The dataGridView1 might display an additional empty row which is also counted in dataGridView1.RowCount in this case you need to start from i = dataGridView1.RowCount-2. Also after you have found a match and removed the row from dataGridView1 it does not make sense to search further for matches for this row, since it is gone. So you should break out of the inner loop and proceed with the next line:

for (int i = dataGridView1.RowCount - 2; i >= 0; i--)
{
    for (int j = 0; j < dataGridView2.RowCount -1; j++)
    {
        string grid2 = dataGridView2.Rows[j].Cells[0].Value.ToString();
        string grid1 = dataGridView1.Rows[i].Cells[0].Value.ToString();
        if (grid1 == grid2)
        {
            dataGridView1.Rows.RemoveAt(i);
            break;
        }
    }
}