当访问的BindingContext [数据源] VS的BindingContext [数据源,数据成员]什么不同呢?数据源、成员、不同、数据

2023-09-09 21:02:33 作者:ヅ心誶☆

我们遇到了一个问题其中

我们有在MDI的工作区结合到两个分开的对象模型的同一个窗口的两个实例。 的对象模型有其 .Equals .GetHash code 方法重写被视为相等。 电话 .EndCurrentEdit()在窗口2触发对窗口1 绑定更新 在两个窗口都设置为使用单独的一个的BindingContext We have two instances of the same window in an MDI workspace bound to two separate object models. The object models have their .Equals and .GetHashCode methods overwritten to be considered equal. Calling .EndCurrentEdit() on window 2 is triggering a binding update for Window 1 Both windows are setup to use separate a BindingContext

我们已经发现该问题已做与主叫

We have discovered the problem has to do with calling

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

如果我们改变,要

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

它工作正常。它也可以正常工作,如果我们去掉了 .Equals .GetHash code 覆盖所以两个对象模型不再被认为是平等的。

It works correctly. It also works correctly if we remove our .Equals and .GetHashCode overrides so the two object models are no longer considered equal.

这是没有道理给我,因为Windows是相同的,因此数据成员属性是一样的了。

That doesn't make sense to me because the windows are the same, so the dataMember property would be the same too.

从this链接,我相信这些调用的定义是:

From this link, I believe the definition of these calls is:

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);
    }

我的数据源不是 ICurrencyManagerProvider

什么是这两个电话之间的差异,以及为什么访问 PropertyManager中仅在数据源结果绑定与另一个窗口单独的的BindingContext 更新?

What is the difference between these two calls, and why does accessing the PropertyManager by only the dataSource result in the bindings for another window with a separate BindingContext being updated?

推荐答案

您没有说明这明确,所以如果你有没有注意到它是在集查找不工作由于等于替换。如您所愿,

You don't state this explicitly, so in case you haven't noticed it is the collection look up that is not working as you expect, because of the equal override.

的BindingContext [数据源] 是使用数据源为重点,对收集的查找

的BindingContext [数据源,数据成员] 是针对集合的查询使用组合键

这是从code表示明确的BindingContext 是维持两个单独的集合。一对数据源键和其他基础上的组合键集合

It is clear from the code that BindingContext is maintaining two separate collections. One a collection on a datasource key and the other a collection based on a composite key.

显然,你等于倍率两次把相似的价值观中的BindingContext [数据源]收集到的数据源,而且会造成一个集合项,因为这些值/密钥是相同的。然而,它会放置的BindingContext [数据源,数据成员]两个条目。

Obviously your override of equal will twice place similar values to datasource in the BindingContext[datasource] collection, but will result in one collection entry, because the values/keys are the same. Whereas, it will place two entries in BindingContext[datasource, datamember].

如果你检查这两个集合,并可以得到的计数您将看到后来收藏有多个条目

If you inspect both collections and can get the counts you'll see that the later collection has more entries.

您必须记住,你有一个评估,以平等,而不是两个引用相同的对象两个不同的对象。这就是问题的症结所在。

You have to remember that you have two separate objects that evaluate to equal, not two references to the same object. This is the crux of the problem.

这样看来,当添加条目到第二个集合(BindingContext中[数据源,数据成员])数据成员的计算结果为唯一的。

It would appear that when adding the entries to the second collection (BindingContext[datasource, datamember]) datamember evaluates to unique.