在WinForms中更新BindingSource不会更新数据源集合

时间:2013-01-28 21:20:25

标签: c# winforms data-binding collections bindingsource

我想在Windows窗体应用中的DataGridView中显示自定义集合。此自定义集合实现ICollectionIEnumerable。我已经使用集合作为.DataSource属性设置了BindingSourceDataGridView设置为使用我的BindingSource作为DataSource。当我使用BindingSource.Add()方法向集合中添加新项目时,DataGridView会正确更新新项目。另一方面,BindingSource数据源不会:

MyCustomCollection myCollection = new MyCustomCollection();

myCollection.Add(myCustomObject1);
myCollection.Add(myCustomObject2);

myBindingSource.DataSource(myCollection);
myBindingSource.Add(myCustomObject3);

在上面的代码中,myBindingSource的内部List包含正确数量的记录(3),DataGridView也包含三个记录,但myCollection只包含两个记录。我知道更改基础myCollection不会更新BindingSourceDataGridView,因为它不是BindingList<T>,但我的印象是直接更新BindingSource将确保myCollection同时更新。

有没有办法使用非BindingList<T>的集合,并在直接与BindingSource进行交互时更新?

更新:我在所有部分(Collection,BindingSource,DataGridView)上更新数据的一种方法如下:

myCollection.Add(myCustomObject3);
myBindingSource.DataSource = null;
myBindingSource.DataSource = myCollection;

我很确定有更好的方法可以解决这个问题,但这是生成我期望的结果的唯一方法。

4 个答案:

答案 0 :(得分:6)

问题是填充适配器。加载表单时,填充已完成。 只需确保执行重新填充,然后在发布任何数据更改后跟进重置绑定,网格将刷新。

示例:

WorkTableAdapter.Insert(objData.XAttribute, "",
  objData.YAttribute,objLoanData.Amount_IsValid, DateTime.Now, DateTime.Now);
this.WorkTableAdapter.Fill(this.POCDataSet.Work);
this.WorkBindingSource.ResetBindings(false);

答案 1 :(得分:2)

如果您使用的容器无法代表您执行此操作,则必须在数据源更改后手动调用ResetBindings()。

http://msdn.microsoft.com/en-us/library/system.windows.forms.bindingsource.resetbindings.aspx

  

使绑定到BindingSource的控件重新读取列表中的所有项目并刷新其显示的值。

答案 2 :(得分:0)

我相信我前一段时间遇到过这个问题 - 我在我的代码中找到了一个文件,我觉得这个解决方案对我有用。

        // Applies pending changes to the underlying data source.
        this.bindingSource1.EndEdit();

这是在保存按钮的点击处理程序的上下文中。

答案 3 :(得分:0)

重置单个项目有效!

如果只有一个项目频繁更改,那么.ResetBindings(false)和重新分配datsource会导致闪烁带来潜在开销。

我使用PropertyChanged尝试了内置机制,但没有更新。

使用ResetItem()重新设定单个项目有效!

        for (int i = 0; i < bindingSource1.Count; i++)
        {
            bindingSource1.ResetItem(i);   
        }

甚至更好 - 如果你有一个更新事件附加到bindningsource中的每个数据项,你可以在绑定源中找到对象并使用对象的索引来调用ResetItem(idx)

在这种情况下,我的自定义事件args包含单独集合中包含的数据对象的字典键。在使用bindningsource.IndexOf()定位对象后,它将被单独刷新。

    void Value_PropertyChanged(object sender, RegisterEventArgs e)
    {

        var idx = bindingSource1.IndexOf(registers_ref[e.registerID]);
        if (idx>=0)
        {
            bindingSource1.ResetItem(idx);                
        }

    }