简体   繁体   中英

Repopulate DataGridView on CellEndEdit

I'm trying to update a value in the database after the user finishes editing a cell. The DataGridView is populated manually (and dynamically) due to some complexities involved in DataBinding this particular data set.

In the event handler for CellEndEdit , I have called my method to update the value back to the database, and it works as planned. The trouble occurs when I attempt to repopulate the DataGridView. For reference, this method is called PopulateAccounts() .

Once a value is entered in the cell, everything works perfectly if the user presses Enter on their keyboard or clicks another control on the form. However, clicking on another cell in the same DataGridView results in the following error:

Operation is not valid because it results in a reentrant call to the SetCurrentCellAddressCore function.

The PopulateAccounts() method includes DataGridView.Rows.Clear() which throws the error. I've researched this error in a few related SO questions, and it seems to be related to threading, which I'm clueless about. One suggested fix is to invoke my PopulateAccounts() method:

BeginInvoke(new MethodInvoker(PopulateAccounts));

This works, but it causes the DataGridView to select all cells preceding the one that was edited (see screenshot below)

faultyDGV

Again, this only happens when clicking out of the cell and into another. Otherwise, ie pressing Enter or clicking on another control, it simply selects the first cell.

Here is the code for PopulateAccounts() for reference:

    // Populates the DataGridView's account records.
    private void PopulateAccounts()
    {
        dgvShed.Rows.Clear();

        using (PassShedEntities context = new PassShedEntities(conString))
        {
            foreach (Account acct in context.Account.Where(a => a.Category_id == (int)lstCategories.SelectedValue))
            {
                dgvShed.Rows.Add();

                foreach (DataGridViewColumn col in dgvShed.Columns)
                {
                    Credential cred = (from c in context.Credential
                                       join f in context.Field on c.Field_id equals f.Id
                                       join a in context.Account on c.Account_id equals a.Id
                                       where c.Account_id == acct.Id
                                       where f.Label == col.Name
                                       select c).SingleOrDefault();

                    dgvShed.Rows[dgvShed.Rows.Count - 1].Cells[col.Name].Tag = cred.Id;
                    dgvShed.Rows[dgvShed.Rows.Count - 1].Cells[col.Name].Value = cred.Value;
                }
            }
        }
    }

Once a value is entered in the cell, everything works perfectly if the user presses Enter on their keyboard or clicks another control on the form

The above actions doesn't change the CurrentCell and the grid repopulation works fine.

However, clicking on another cell in the same DataGridView results in the following error:

When you click on another cell the CurrentCell of the datagridview is changing and grid internally calls the SetCurrentCellAddressCore to do the cell change. This call internally raises CellEndEdit event which triggers the SetCurrentCellAddressCore again and this cycle goes on resulting in infinite loop. The DataGridView detects this loop and throws exception resulting in the error you have mentioned.

In the above case the my guess is that DataGridView somehow goofed up the selection of cells. You could simply clear the selection at the end of PopulateAccounts with DataGridView.ClearSelection() method.

I've been wrestling with just about the exact same problem and just came up with a solution that works with my specifics. I moved all the code from the CellEndEdit event to the CellValueChanged event (which fires right before the former) and now both options for ending the cell-edit: the enter-stroke and clicking off to another cell, work great.

I'm not sure what the perfectly proper way to use the events is, but this seems to be working!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM