Click here to Skip to main content
14,739,403 members
Please Sign up or sign in to vote.
2.50/5 (2 votes)
See more:
Please could anyone point me in the right direction for the reentrant exceptions I'm getting when I try and change the datasource of a DataGridView control. Below is a cut down example of the problem that I am currently unable to find a suitable solution for. I come from a Visual Foxpro background where this sort of thing is easily possible.

The only way I've partially solved this is by running a thread to update the datasource but because this is asynchronous there is a small chance that the update will not happen. Another way that works is to have a separate button control to reorder the data but this involves the user pressing it - a much better way would be to automate it after the cell update.

I understand why the grid gets upset on changing a datasource when editing data of another source. I also know that the DataGridView can be set to sort on columns but I want to do more than just sort in my full version.

To run the code below add a DataGridView (naming it dgv1) to a form. Then to make the exception happen change the cell that has the 9 in to a 3 and then move off the cell by either clicking another cell or using the arrow keys. If enter is pressed before highlighting another cell then the exception doesn't occur but nor does the grid get reordered.

// standard libraries added by ide
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace dgv_test
{
    public partial class Form1 : Form
    {
        private List<dv> grid;
        public Form1()
        {
            InitializeComponent();
            // this would be from a database
            List<dv> data = new List<dv>
                            {
                                new dv{ desc="t1", order=1},
                                new dv{ desc="t2", order=2},
                                new dv{ desc="t3", order=9},
                                new dv{ desc="t4", order=4},
                                new dv{ desc="t5", order=5},
                            };
            // in memory list
            grid =
                (from lu in data
                 orderby lu.order
                 select new dv
                 {
                     desc = lu.desc,
                     order = lu.order
                 }).ToList();

            // grid list
            dgv1.DataSource =
                (from g in grid
                 orderby g.order
                 select new dv
                 {
                     desc = g.desc,
                     order = g.order
                 }).ToList();
            // make description column readonly
            dgv1.Columns[0].ReadOnly = true;
        }
        private void dgv1_CellLeave(object sender, DataGridViewCellEventArgs e)
        {
            // only update memory copy if order column changed
            if (dgv1.CurrentCellAddress.X == 1 && dgv1.IsCurrentCellDirty)
            {
                // grid is in memory copy of grid data
                grid.ElementAt(dgv1.CurrentCellAddress.Y).order = int.Parse(dgv1.CurrentCell.EditedFormattedValue.ToString());
                rgrid();
            }
        }
        // this is the function to update datagridview control
        private void rgrid()
        {
            // query the in memory list from the database
            var gx =
                (from g in grid
                 orderby g.order
                 select new dv
                 {
                     desc = g.desc,
                     order = g.order
                 }).ToList();
            // set the datagridview control with the newly ordered set
            dgv1.DataSource = gx.ToList();
            // do the same for the in memory list so that both are in alinement
            grid = gx.ToList();
        }
    }
    class dv
    {
        public string desc { get; set; }
        public int order { get; set; }
    }
}


Thanks in advance of any suggestions.
Posted

1 solution

If you change the update code to the CellValueChanged event instead of the CellLeave event this should cure your ills.

Hope this helps
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900