我们遇到了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
    这两个调用之间有什么区别,为什么仅通过PropertyManager访问dataSource会导致另一个窗口的绑定(bind)更新了单独的BindingContext

    最佳答案

    您没有明确说明这一点,因此,如果您没有注意到是集合查找没有按您期望的那样工作,因为等于覆盖。

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

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

    从代码中很明显, BindingContext 正在维护两个单独的集合。一个集合是基于数据源键的集合,另一个集合是基于组合键的集合。

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

    如果您同时检查了两个集合,并且可以得到的计数,则您会看到后面的集合中还有个条目

    您必须记住,您有两个单独的对象求值相等,而不是两个引用相同的对象。这是问题的症结所在。

    似乎在将条目添加到第二个集合(BindingContext [datasource,datamember])时,数据成员评估为唯一。

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

    10-10 13:45