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.
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();
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},
};
grid =
(from lu in data
orderby lu.order
select new dv
{
desc = lu.desc,
order = lu.order
}).ToList();
dgv1.DataSource =
(from g in grid
orderby g.order
select new dv
{
desc = g.desc,
order = g.order
}).ToList();
dgv1.Columns[0].ReadOnly = true;
}
private void dgv1_CellLeave(object sender, DataGridViewCellEventArgs e)
{
if (dgv1.CurrentCellAddress.X == 1 && dgv1.IsCurrentCellDirty)
{
grid.ElementAt(dgv1.CurrentCellAddress.Y).order = int.Parse(dgv1.CurrentCell.EditedFormattedValue.ToString());
rgrid();
}
}
private void rgrid()
{
var gx =
(from g in grid
orderby g.order
select new dv
{
desc = g.desc,
order = g.order
}).ToList();
dgv1.DataSource = gx.ToList();
grid = gx.ToList();
}
}
class dv
{
public string desc { get; set; }
public int order { get; set; }
}
}
Thanks in advance of any suggestions.