访问BindingContext [dataSource]和BindingContext [dataSource,dataMember]时有什么不同?

Rac*_*hel 13 c# binding .net-3.5 winforms

我们遇到了一个问题,在那里

  • 我们在MDI工作空间中有两个相同窗口的实例绑定到两个单独的对象模型.
  • 对象模型将其覆盖的方法.Equals.GetHashCode方法视为相等.
  • 调用.EndCurrentEdit()窗口2会触发窗口1的绑定更新
  • 两个窗口都设置为使用单独的a BindingContext

我们发现这个问题与调用有关

((PropertyManager)ctrl.BindingContext[dataSource]).EndCurrentEdit();
Run Code Online (Sandbox Code Playgroud)

如果我们改变它

((PropertyManager)ctrl.BindingContext[dataSource, dataMember]).EndCurrentEdit();
Run Code Online (Sandbox Code Playgroud)

它工作正常.如果我们删除我们的.Equals.GetHashCode覆盖,它也可以正常工作,因此两个对象模型不再被认为是相等的.

这对我来说没有意义,因为窗户是相同的,所以dataMember属性也是一样的.

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

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);
    }
Run Code Online (Sandbox Code Playgroud)

dataSource不是ICurrencyManagerProvider

这两个调用之间有什么区别,为什么PropertyManager只通过dataSource另一个窗口的绑定访问结果而另一个窗口BindingContext被更新?

nem*_*Bu4 0

当你访问时BindingContext[dataSource],你实际上在访问BindingContext[dataSource, ""]。因此,除了 HashCode 之外没有任何区别,它使用DataSourceDataMember值进行计算,可以在您的链接中看到。

public override int GetHashCode() {
    return dataSourceHashCode * dataMember.GetHashCode();
}
Run Code Online (Sandbox Code Playgroud)

单独对象中的问题BindingContext可能是它们未正确填充。