【问题标题】:Updating of BindingSource in WinForms does not update Datasource Collection在 WinForms 中更新 BindingSource 不会更新数据源集合
【发布时间】:2013-01-28 21:20:24
【问题描述】:

我想在 Windows 窗体应用程序的 DataGridView 中显示自定义集合。这个自定义集合实现了ICollectionIEnumerable。我设置了一个BindingSource,将集合用作 .DataSource 属性。 DataGridView 设置为使用我的BindingSource 作为数据源。当我使用 BindingSource.Add() 方法将新项目添加到集合中时,DataGridView 会随着新项目正确更新。另一方面,BindingSource 数据源却没有:

MyCustomCollection myCollection = new MyCustomCollection();

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

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

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

有没有办法使用不是BindingList<T> 的集合并在直接与BindingSource 交互时更新它?

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

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

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

【问题讨论】:

标签: c# winforms data-binding collections bindingsource


【解决方案1】:

问题是填充适配器。当您加载表单时,Fill 已为您完成。 只需确保进行 Refill,然后在任何数据更改后使用 Reset 绑定跟进,Grid 就会刷新。

例子:

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

    • 我查看了 ResetBindings(),但它没有产生正确的结果。通过查看文档,该示例似乎表明如果我更新基础集合,而不是直接调用 BindingSource,则应调用 ResetBindings()。
    【解决方案3】:

    重置单个项目有效!

    我对 .ResetBindings(false) 没有运气,如果只有一项频繁更改,重新分配 datsource 会导致潜在开销闪烁。

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

    使用 ResetItem() 重置单个项目有效!

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

    甚至更好——如果你有一个更新事件附加到绑定源中的每个数据项,你可以在绑定源中找到对象并使用对象的索引来调用 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);                
            }
    
        }
    

    【讨论】:

      【解决方案4】:

      我相信我不久前遇到了这个问题 - 我在我的代码的文件中找到了,我认为这是对我有用的解决方案。

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

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

      【讨论】:

      • 感谢您的提示!我试过这个,它没有效果。 EndEdit 的文档似乎表明,如果数据源包含的对象没有实现“IEditableObject”,它将什么也不做。 Link
      • +1 这对我有用.. 我不是在按钮上下文中添加它,而是在将 bindingSource 重新附加到 grid.DataSource 的线程中添加它
      • 这种对我有用,但出于某种奇怪的原因,第一次更改不起作用,但对后续更改起作用,
      猜你喜欢
      • 1970-01-01
      • 2012-11-06
      • 1970-01-01
      • 2020-06-13
      • 2021-09-15
      • 1970-01-01
      • 2012-01-18
      • 1970-01-01
      相关资源
      最近更新 更多