2016-08-18 43 views
1

我已經綁定我DataGridViewBindingSource,但是當我打電話ResetBinding()DataGridView沒有更新,只顯示那些已WhenDeleted列值作爲空記錄:BindingSource.BindingReset不工作

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。 幫助表示讚賞。

回答

1

爲什麼這段代碼不起作用?

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

讓我們來看看原因。 有2個問題,在上面的代碼:

  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";或者即使你使用labourCollection.RemoveAt(0);列表中刪除項目DataGridView不會顯示Property新的價值,甚至是不知道刪除的項目的更改列表中的LABOUR財產。

如果您致電bs.ResetBindings(false)DataGridView顯示新的屬性值。也不顯示刪除的項目。

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

謝謝Reza的詳細解釋。我試着BindingSource的Filter屬性只包含那些WhereDeleted爲空的記錄。但後來它說我的列表(本地在我的情況下)應該實現IBindingListView所需的結果。不知道如何實現,沒有bs.DataSource = labourCollection;在btnDel_Click事件 – Sadiq

+0

不客氣。設置屬性值後,可以從'labourCollection'中刪除該項目。別擔心,它不會從上下文中刪除。它只會從'labourCollection'中刪除。 –

+0

再次設置數據源不是什麼大問題,這有什麼問題? –