0

Background:

A WinForms form has two DataGridView controls, DataGridView1 and DataGridView2 (with SelectionMode property set to FullRowSelect) as shown in the uploaded pictures. Both the DataGridView controls list products and have the same set of columns (with an additional checkbox column in DataGridView1). The Quantity column is editable, and when edited the Amount column is updated. The objective is, when changes are made in one DataGridView control, the same is reflected in the other DataGridView control.

Data Model:

public class Product : INotifyPropertyChanged
{
  public string Code { get; set; }
  
  public string Name { get; set; }
  
  private int quantity;
  public int Quantity
  {
    get { return this.quantity; }
    set
    {
      this.quantity = value;
      this.OnPropertyChanged();
    }
  }
}

public class ProductCollection : Collection<Product>
{
}

Data Binding:

BindingSource bs1 = new BindingSource();
bs1.DataSource = pc1; // pc1 is the ProductCollection from database as a result of search

dataGridView1.DataSource = bs1;

BindingSource bs2 = new BindingSource();
bs2.DataSource = new ProductCollection();

dataGridView2.DataSource = bs2;

Usage:

  1. The user performs a search and one or more products are loaded in the DataGridView1 from the database based on the search text.
  2. The user then edits the Quantity column as needed, which updates the Amount column accordingly.
  3. The user then selects the products, using the checkbox against each row, and then clicks the 'Add to Product List' button to add the selected products to the DataGridView2.

...

private void AddProductsButton_Click(sender, e)
{
  for (int rowIndex = 0; rowIndex < this.dataGridView1.RowCount; rowIndex++)
  {
    DataGridViewRow row = this.dataGridView1.Rows[rowIndex];
    DataGridViewCheckBoxCell cell = (DataGridViewCheckBoxCell)row.Cells[0];

    if (cell.IsChecked())
    {
      Product product = (Product)row.DataBoundItem;

      this.bs2.Add(product);
      cell.Uncheck();
    }
  }
}

So far so good!

Issues:

  1. When the Quantity column is updated in one DataGridView control, the changes reflect immediately in the other DataGridView control ONLY for a row that is currently highlighted (selected). For a non-selected row, the changes do not reflect immediately. And, just as I do anything that causes the DataGridView to be repainted, the updated values show up.
  2. In DataGridView1, after a selected (checked) product is added to DataGridView2, the cell is programmatically unchecked (see code above). The cell is visually unchecked for all rows except the one that is highlighted (though the underlying cell value is false). And similar to the above issue, as I do anything that causes the DataGridView to be repainted, the check mark vanishes.

I have tried to depict the issues in the attached screenshots (as much as possible).

DataGridView1: DataGridView1

DataGridView2: DataGridView2

  • 1
    [Use a bindinglist datasource or call refresh on the datagridview.](https://stackoverflow.com/a/1118992/3585500) Scrolling that link gives other suggestions that might work as well. – ourmandave Aug 18 '23 at 11:13
  • @ourmandave - I have reviewed the above SO link and it didn't help. My issue is not with data binding but a UI refresh issue because everything works as expected on the selected row. – Santhosh Shanmugam Aug 18 '23 at 13:03

1 Answers1

0

I was able to fix issue #2 with the below code:

private void DataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
  if (dataGridView1.CurrentCell is DataGridViewCheckBoxCell && dataGridView1.IsCurrentCellDirty)
  {
    dataGridView1.EndEdit(DataGridViewDataErrorContexts.Commit);
  }
}