BindingSource.BindingReset 不工作

BindingSource.BindingReset not working

我将我的 DataGridView 绑定到 BindingSource 但是当我调用 ResetBinding()DataGridView 不会更新以仅显示那些具有 WhenDeleted 列的记录值为空:

public partial class LabourSetup : DisplayControl
{
    private List<LABOUR> labourCollection = new List<LABOUR>();
    protected BindingSource bs = new BindingSource();
    private void PopulateGrid()
    {
        labourCollection = Query.GetLabours();
        bs.DataSource = labourCollection;
        this.dataGridViewX1.DataSource = bs;
    }
    // This method doesn't actually delete Labour from table just mark the column with the present day date. So that it could not be shown in Grid View
    public void btnDel_Click(object sender, EventArgs e)
    {
        if(dataGridViewX1.SelectedRows.Count == 1)
        {
            dataGridViewX1.SelectedRows[0].Cells["WhenDeleted"].Value = DateTime.Now;
        }
        MainForm.GlobalCache.SaveChanges();
        labourCollection = Query.GetLabours();
        //bs.DataSource = labourCollection;  // works when I un comment this line
        bs.ResetBindings(false);  // doesnt work
        }
    }
}

上面为什么要写:

//bs.DataSource = labourCollection;  // works when I un comment this line. Why?

因为绑定源已经绑定到 PopulateGrid() 方法中的 labourCollection。 ResetBinding() 不应显示标记为删除的记录(WhenDeleted 不为空)。

public class Query
{
    internal static List<LABOUR> GetLabours()
    {
   // Getting only those records which are not marked for deletion
      return MainForm.GlobalCache.LABOURs.Local.Where(lab => lab.WhenDeleted == null).ToList();
    }
}

上面GlobalCacheDbContext。 感谢帮助。

为什么此代码不起作用?

labourCollection = Query.GetLabours();
bs.ResetBindings(false);  

让我们看看原因。 上面的代码有两个问题:

  1. labourCollection = Query.GetLabours();bsDataSource 没有任何影响。它只是将一个新列表分配给 labourCollection 变量。但是以前的列表仍在内存中。 labourCollection 仅指向新列表,但 bs 使用您分配给其 DataSource 属性 的列表。所以更改的项目仍然存在于您用作 bsDataSource 的列表中。
    记住 reference type 个概念。如果将新对象分配给变量,则前一个对象将保持不变。您只是错过了指向该对象的指针,而变量指向了新对象。

  2. ResetBindings 方法只会导致绑定到 BindingSource 的控件重新读取列表中的所有项目并刷新它们的显示值。它不会从数据库或其他地方重新加载数据。它只是查看 DataSource 并再次显示绑定控件中的数据。因此,您更改的值将出现在列表中,您不能指望 ResetBindings 为您执行任何特殊操作。

为什么这段代码有效?

labourCollection = Query.GetLabours();
bs.DataSource = labourCollection;
bs.ResetBindings(false); 

因为 bs.DataSource = labourCollection; 才起作用。最后一行代码没用。当您将新列表分配给 BindingSourceDataSource 时,它会导致刷新绑定控件,您不需要调用 ResetBindings.

ResetBindings有什么用?

当数据源不支持双向数据绑定时,刷新网格以显示来自数据源的值很有用。

如果您使用 labourCollection[0].Property = "Value"; 更改列表中 LABOUR 的 属性,或者即使您使用 labourCollection.RemoveAt(0); 从列表中删除一个项目,DataGridView 不会显示 Property 的新值,甚至它不知道已删除的项目。

如果您调用 bs.ResetBindings(false)DataGridView 会显示 属性 的新值。也不显示已删除的项目。

labourCollection[0].SomeProperty = "Some Value";
bs.ResetBindings(false);