gpt4 book ai didi

c# - 访问 BindingContext[dataSource] 与 BindingContext[dataSource, dataMember] 有什么不同?

转载 作者:可可西里 更新时间:2023-11-01 08:13:34 35 4
gpt4 key购买 nike

我们遇到了一个 problem哪里

  • 我们在一个 MDI 工作区中有两个相同窗口的实例,它们绑定(bind)到两个单独的对象模型。
  • 对象模型覆盖了它们的 .Equals.GetHashCode 方法以被视为相等。
  • 在窗口 2 上调用 .EndCurrentEdit() 会触发窗口 1 的绑定(bind)更新
  • 两个窗口都设置为使用单独的 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

这两个调用之间有什么区别,为什么仅通过 dataSource 访问 PropertyManager 会导致绑定(bind)另一个具有单独 BindingContext 的窗口 正在更新?

最佳答案

您没有明确说明这一点,以防万一您没有注意到 collection 查找没有按您预期的那样工作,因为 equal 覆盖。

BindingContext[datasource] 是使用datasource 作为键 对集合的查找。

BindingContext[datasource, datamember]使用复合键对集合的查找。

从代码中可以清楚地看出,BindingContext 维护着两个独立的集合。一个基于数据源键的集合,另一个基于复合键的集合。

显然,您对 equal 的覆盖将两次将相似的值放置到 BindingContext[datasource] 集合中的数据源中,但会产生一个集合条目,因为值/键是相同的。然而,它将在 BindingContext[datasource, datamember] 中放置两个条目。

如果您检查这两个集合并获得计数,您会发现后面的集合有更多条目

您必须记住,您有两个计算结果相等的独立对象,而不是对同一对象的两个引用。这就是问题的关键。

当将条目添加到第二个集合 (BindingContext[datasource, datamember]) 时,datamember 的计算结果似乎是唯一的。

关于c# - 访问 BindingContext[dataSource] 与 BindingContext[dataSource, dataMember] 有什么不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24189351/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com