我有一个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中似乎没有任何这样的东西,或者我错过了什么?
答案 0 :(得分:17)
要让DataGridView
获取对其DataSource
的更改,源代码应实现IBindingList。 List<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();
希望它有所帮助。