2014-06-12 24 views
12

我們遇到了一個problem,其中當訪問BindingContext [dataSource] vs BindingContext [dataSource,dataMember]時有什麼不同?

  • 我們擁有同一個窗口的兩個實例綁定到兩個不同的對象模型的MDI工作區。
  • 對象模型的.Equals.GetHashCode方法被覆蓋爲等同。
  • 上調用窗口2 .EndCurrentEdit()被觸發綁定更新窗口1
  • 兩個窗口都設置爲使用單獨一個BindingContext

我們已經發現的問題與調用

((PropertyManager)ctrl.BindingContext[dataSource]).EndCurrentEdit(); 

如果我們將其更改爲

((PropertyManager)ctrl.BindingContext[dataSource, dataMember]).EndCurrentEdit(); 

它工作正常。如果我們刪除我們的.Equals.GetHashCode覆蓋,這兩個對象模型不再被認爲是相等的,它也能正常工作。

這對我來說沒有意義,因爲窗口是相同的,所以dataMember屬性也是一樣的。

this link,我相信這些電話的定義是:

public BindingManagerBase this[object dataSource] { 
    get { 
     return this[dataSource, ""]; 
    } 
} 

public BindingManagerBase this[object dataSource, string dataMember] { 
    get { 
     return EnsureListManager(dataSource, dataMember); 
    } 

internal BindingManagerBase EnsureListManager(object dataSource, string dataMember) { 
    BindingManagerBase bindingManagerBase = null; 

    if (dataMember == null) 
     dataMember = ""; 

    // Check whether data source wants to provide its own binding managers 
    // (but fall through to old logic if it fails to provide us with one) 
    // 
    if (dataSource is ICurrencyManagerProvider) { 
     bindingManagerBase = (dataSource as ICurrencyManagerProvider).GetRelatedCurrencyManager(dataMember); 

     if (bindingManagerBase != null) { 
      return bindingManagerBase; 
     } 
    } 

    // Check for previously created binding manager 
    // 
    HashKey key = GetKey(dataSource, dataMember); 
    WeakReference wRef; 
    wRef = listManagers[key] as WeakReference; 
    if (wRef != null) 
     bindingManagerBase = (BindingManagerBase) wRef.Target; 
    if (bindingManagerBase != null) { 
     return bindingManagerBase; 
    } 

    if (dataMember.Length == 0) { 
     // No data member specified, so create binding manager directly on the data source 
     // 
     if (dataSource is IList || dataSource is IListSource) { 
      // IListSource so we can bind the dataGrid to a table and a dataSet 
      bindingManagerBase = new CurrencyManager(dataSource); 
     } 
     else { 
      // Otherwise assume simple property binding 
      bindingManagerBase = new PropertyManager(dataSource); 
     } 
    } 
    else { 
     // Data member specified, so get data source's binding manager, and hook a 'related' binding manager to it 
     // 
     int lastDot = dataMember.LastIndexOf("."); 
     string dataPath = (lastDot == -1) ? "" : dataMember.Substring(0, lastDot); 
     string dataField = dataMember.Substring(lastDot + 1); 

     BindingManagerBase formerManager = EnsureListManager(dataSource, dataPath); 

     PropertyDescriptor prop = formerManager.GetItemProperties().Find(dataField, true); 
     if (prop == null) 
      throw new ArgumentException(SR.GetString(SR.RelatedListManagerChild, dataField)); 

     if (typeof(IList).IsAssignableFrom(prop.PropertyType)) 
      bindingManagerBase = new RelatedCurrencyManager(formerManager, dataField); 
     else 
      bindingManagerBase = new RelatedPropertyManager(formerManager, dataField); 
    } 

dataSource不是ICurrencyManagerProvider

是這兩個調用之間的區別,以及爲什麼只訪問PropertyManagerdataSource導致另一個窗口的綁定正在更新,並且單獨的BindingContext

+0

在這個問題上沒有人認爲這是一個恥辱,我覺得這個問題很有趣。 – DonBoitnott

回答

0

當您訪問BindingContext[dataSource]時,您實際訪問BindingContext[dataSource, ""]。因此,除了使用DataSourceDataMember值進行計算的HashCode之外,沒有區別,可以在link中看到。

public override int GetHashCode() { 
    return dataSourceHashCode * dataMember.GetHashCode(); 
} 

在單獨BindingContext對象的問題可能是,他們沒有正確填寫。

1

你沒有明確說明這一點,所以如果你沒有注意到它是收集查找不工作,因爲等於覆蓋的像您期望的。

的BindingContext [數據源]是針對使用數據源作爲密鑰集合中查找。

的BindingContext [數據源,數據成員]是針對集合查找使用複合密鑰

正是從這一的BindingContext是維持兩個單獨集合代碼清晰。一個是數據源密鑰的集合,另一個是基於複合密鑰的集合。

顯然你的平等倍率兩次將類似值的BindingContext [數據源]集合中的數據源,而且會造成一個集入境,因爲值/密鑰是相同的。而它將在BindingContext [datasource,datamember]中放置兩個條目。

如果你檢查這兩個集合,並可以得到計數,你會看到,後來集合了多個條目

你要記住,你必須評估爲相等,而不是兩個引用同一對象兩個不同的對象。這是問題的關鍵。

這樣看來,將所述條目添加到第二收集時(的BindingContext [數據源,數據成員])數據成員的計算結果爲唯一的。

+1

簡單地說:您的等價重寫返回true,儘管它們實際上並不等於對象。 – pashute

相關問題