2009-09-16 78 views
4

我有一个WinForm应用程序与多个DataGridViews绑定到SortableBindingLists。当行被删除时刷新DataGridView绑定到列表

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

我似乎无法让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(); 

    } 

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

回答

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

+4

这是超级老,但它接近谷歌的顶部,所以我会在这里抛出一些东西。切换到绑定列表100%完美。其次,如果您使用绑定源方式,如果您在原始列表上运行添加/移除,则无法看到在DataGridView上反映的更改。您需要运行绑定源上的添加/删除。 – MindingData 2012-09-20 06:19:54

0

尝试

dataGridView1.Refresh() 
+0

谢谢,迈克尔,但它给出了相同的结果。我尝试使用Refresh替换Invalidate调用,并且还试图在Invalidate和之前添加Refresh,然后再添加Refresh。所有人仍然抛出同样的例外。 – 2009-09-16 21:26:19

1

好吧,因为我没有得到任何有用的答复,我会继续前进,用杂牌组装电脑,我拿出。

如果您使用反射进入DataGridView.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(); 
    } 

如果任何人有任何更好的想法(我敢肯定有必须有一些在那里),请让我知道。

+0

我得到了同样的错误,因为你的和我的场景是lil有点相同的东西,即读ford循环中的datadridview的数据,并在每一行做一些操作,最后删除当前行...所以我做了什么创建一个委托函数删除它因为我使用后台工作线程...它的工作为... ru使用ne背景线程 – FosterZ 2010-11-04 10:29:26

+0

安德鲁瓦特发布了一个非常好的答案。你的回答既不好,也不好。请在安德鲁的帖子上打勾。 – dzendras 2011-09-09 09:22:40

+0

dzendras - 同意。 – 2011-09-10 18:00:32

0

我已经尝试过使用容器对象的Validate()方法,并且它在同步数据网格视图和绑定数据表时工作顺利。

在Visual C++一个例子可以被给定为:

//假设DGV已经在代码创建为一个数据网格视图对象

的SplitContainer^dgvContainer = dynamic_cast的(dgv->父 - >父); dgvContainer - > Validate();

希望它有帮助。

相关问题