开发者

Changing the datasource in a DataGridView after cell editing

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 t开发者_开发百科he 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 nor does the grid get reordered.

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; }
}
}


Try moving your code to the CellValueChanged event of the DataGridView and it should work fine.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜