删除行时,将DataGridView绑定刷新到列表

Dav*_*nna 4 data-binding datagridview winforms

我有一个WinForm应用程序,其中多个DataGridViews绑定到SortableBindingLists.

在某些情况下,我需要以编程方式从列表中删除网格绑定的项目.

我似乎无法让DGV认识到它的数据发生了变化,或者特别是它的行数较少.我正在调用dataGridView1.Invalidate(),它正在重新绘制网格,但它尝试重绘与之前一样多的行,并抛出一系列"索引不存在"的异常,每个列都有一个例外.

这是一个展示问题的简化代码示例:(只是带有DGV和按钮的WinForm.)

    private List<Employee> list;
    private void Form1_Load(object sender, EventArgs e)
    {
        list = new List<Employee>();
        for (int ix = 0; ix < 3; ix++)
        {
            list.Add(ObjectMother.GetEmployee(ix+1));
        }

        dataGridView1.DataSource = list;
    }

    private void cmdDeleteARow_Click(object sender, EventArgs e)
    {
        list.Remove(list[0]);
        dataGridView1.Invalidate();

    }
Run Code Online (Sandbox Code Playgroud)

在ASP.NET中,当使用GridView控件时,可以调用"DataBind()"方法来强制它刷新数据.在WinForms中似乎没有任何这样的东西,或者我错过了什么?

And*_*att 17

为了获得DataGridView对其的更改DataSource,源应该实现IBindingList.List<T>没有,所以它没有广播它的变化,并且 DataGridView不知道它需要更新.

在这种情况下一个简单的解决方法是在列表和之间放置一个BindingSourceDataGridView,然后调用Remove()它:

private List<Employee> list;
private BindingSource bindingSource;
private void Form1_Load(object sender, EventArgs e)
{
    list = new List<Employee>();
    for (int ix = 0; ix < 3; ix++)
    {
        list.Add(ObjectMother.GetEmployee(ix+1));
    }

    dataGridView1.DataSource = bindingSource;
    bindingSource.DataSource = list;
}

private void cmdDeleteARow_Click(object sender, EventArgs e)
{
    bindingSoruce.Remove(list[0]); // or, RemoveAt(0)

    // Probably not necessary:
    // dataGridView1.Invalidate();
}
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用BindingList<T>而不是List<T>创建自己的实现列表类IBindingList.

  • 这是超级老,但它接近谷歌的顶部,所以我会在这里抛出一些东西.切换到BindingList 100%完美无缺.其次,有些事情让我感到困惑,如果你使用bindingsource方式,如果你在原始列表上运行add/removed,你将看不到DataGridView上反映的变化.您需要在bindingsource上运行add/removed. (4认同)