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

时间:2009-09-16 21:08:04

标签: winforms datagridview data-binding

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

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

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

这是一个展示问题的简化代码示例:(只是带有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();

    }

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

4 个答案:

答案 0 :(得分:17)

要让DataGridView获取对其DataSource的更改,源代码应实现IBindingListList<T>没有,因此它不会广播其更改,DataGridView不知道它需要更新。

在这种情况下,一个简单的解决方法是在列表和DataGridView之间添加BindingSource,然后在其上调用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();
}

或者,您可以使用BindingList<T>代替List<T>,也可以创建自己的列表类来实现IBindingList

答案 1 :(得分:1)

好吧,既然我没有得到任何有用的回复,我会继续使用我想出的那些kludge。

如果使用反射进入DataGridView.DataSource属性,您将看到仅在DataSource更改时才调用绑定方法。请注意,对DataSource内容的更改(例如,添加,更改或删除列表元素)不会被识别为对DataSource的更改。为了强制调用数据绑定方法,我成功完成的工作是将DataSource重新分配给其他对象,然后将其分配回列表。看起来令人难以置信的kludgy,以及CPU周期的巨大浪费,但它似乎工作。所以代码变成了:

    private void cmdDeleteARow_Click(object sender, EventArgs e)
    {
        list.Remove(list[0]);
        dataGridView1.DataSource = new List<Employee>();
        dataGridView1.DataSource = list;
        dataGridView1.Invalidate();
    }

如果有人有更好的想法(我确定必须有一些),请告诉我。

答案 2 :(得分:0)

尝试

dataGridView1.Refresh()

答案 3 :(得分:0)

我尝试过使用容器对象的Validate()方法,它在同步数据网格视图和绑定数据表时运行顺畅。

Visual C ++中的示例可以是:

//假设已经在代码中创建了dgv作为数据网格视图对象

SplitContainer ^ dgvContainer = dynamic_cast(dgv-&gt; Parent-&gt; Parent); dgvContainer - &gt; Validate();

希望它有所帮助。