internal void RegisterCollectionSynchronizationCallback( IEnumerable collection, object context, CollectionSynchronizationCallback synchronizationCallback) { CollectionRecord cr = EnsureCollectionRecord(collection); cr.SynchronizationInfo = new SynchronizationInfo(context, synchronizationCallback); ViewTable vt = cr.ViewTable; if (vt != null) { bool isSynchronized = cr.SynchronizationInfo.IsSynchronized; foreach (DictionaryEntry de in vt) { ViewRecord vr = (ViewRecord)de.Value; CollectionView cv = vr.View as CollectionView; if (cv != null) { cv.SetAllowsCrossThreadChanges(isSynchronized); } } } }
// remove entries whose key (CVS) has been GC'd, and whose collection // view is no longer in use. Return true if anything got removed, // or if there are no entries left internal bool Purge() { ArrayList al = new ArrayList(); foreach (DictionaryEntry de in this) { WeakRefKey key = (WeakRefKey)de.Key; if (key.Target == null) { ViewRecord vr = (ViewRecord)de.Value; CollectionView cv = vr.View as CollectionView; if (cv != null) { if (!cv.IsInUse) { // tell the corresponding CollectionView to detach cv.DetachFromSourceCollection(); al.Add(key); // mark this entry for removal } } else { al.Add(key); } } } for (int k = 0; k < al.Count; ++k) { this.Remove(al[k]); } return(al.Count > 0 || this.Count == 0); }
// Token: 0x060076FF RID: 30463 RVA: 0x00220044 File Offset: 0x0021E244 private ViewRecord CacheView(object collection, CollectionViewSource cvs, CollectionView cv, ViewRecord vr) { CollectionRecord collectionRecord = this[collection]; ViewTable viewTable = collectionRecord.ViewTable; if (viewTable == null) { viewTable = new ViewTable(); collectionRecord.ViewTable = viewTable; if (!(collection is INotifyCollectionChanged)) { this._inactiveViewTables.Add(viewTable, 2); } } if (vr == null) { vr = new ViewRecord(cv); } else if (cv == null) { cv = (CollectionView)vr.View; } cv.SetViewManagerData(viewTable); viewTable[cvs] = vr; return(vr); }
// Token: 0x060076E5 RID: 30437 RVA: 0x0021F950 File Offset: 0x0021DB50 internal bool Purge() { ArrayList arrayList = new ArrayList(); foreach (object obj in this) { DictionaryEntry dictionaryEntry = (DictionaryEntry)obj; WeakRefKey weakRefKey = (WeakRefKey)dictionaryEntry.Key; if (weakRefKey.Target == null) { ViewRecord viewRecord = (ViewRecord)dictionaryEntry.Value; CollectionView collectionView = viewRecord.View as CollectionView; if (collectionView != null) { if (!collectionView.IsInUse) { collectionView.DetachFromSourceCollection(); arrayList.Add(weakRefKey); } } else { arrayList.Add(weakRefKey); } } } for (int i = 0; i < arrayList.Count; i++) { base.Remove(arrayList[i]); } return(arrayList.Count > 0 || base.Count == 0); }
// Token: 0x060074B4 RID: 29876 RVA: 0x002162AC File Offset: 0x002144AC internal ViewRecord GetViewRecord(object collection, CollectionViewSource key, Type collectionViewType, bool createView, Func <object, object> GetSourceItem) { if (this.IsShutDown) { return(null); } ViewRecord viewRecord = this._viewManager.GetViewRecord(collection, key, collectionViewType, createView, GetSourceItem); if (viewRecord != null && !viewRecord.IsInitialized) { this.ScheduleCleanup(); } return(viewRecord); }
// return an existing view (or null if there isn't one) over the collection private ViewRecord GetExistingView(object collection, CollectionViewSource cvs, Type collectionViewType, Func <object, object> GetSourceItem) { ViewRecord result; CollectionView cv = collection as CollectionView; if (cv == null) { // look up cached entry CollectionRecord cr = EnsureCollectionRecord(collection, GetSourceItem); ViewTable vt = cr.ViewTable; if (vt != null) { ViewRecord vr = vt[cvs]; if (vr != null) { cv = (CollectionView)vr.View; } result = vr; // activity on the VT - reset its expiration date if (_inactiveViewTables.Contains(vt)) { _inactiveViewTables[vt] = InactivityThreshold; } } else { result = null; } } else { // the collection is already a view, just use it directly (no tables needed) result = new ViewRecord(cv); } if (cv != null) { ValidateViewType(cv, collectionViewType); } return(result); }
internal ViewRecord GetViewRecord(object collection, CollectionViewSource key, Type collectionViewType, bool createView, Func <object, object> GetSourceItem) { if (IsShutDown) { return(null); } ViewRecord record = _viewManager.GetViewRecord(collection, key, collectionViewType, createView, GetSourceItem); // lacking any definitive event on which to trigger a cleanup pass, // we use a heuristic, namely the creation of a new view. This suggests // that there is new activity, which often means that old content is // being replaced. So perhaps the view table now has stale entries. if (record != null && !record.IsInitialized) { ScheduleCleanup(); } return(record); }
// Token: 0x060076FA RID: 30458 RVA: 0x0021FEC8 File Offset: 0x0021E0C8 internal void RegisterCollectionSynchronizationCallback(IEnumerable collection, object context, CollectionSynchronizationCallback synchronizationCallback) { CollectionRecord collectionRecord = this.EnsureCollectionRecord(collection, null); collectionRecord.SynchronizationInfo = new SynchronizationInfo(context, synchronizationCallback); ViewTable viewTable = collectionRecord.ViewTable; if (viewTable != null) { bool isSynchronized = collectionRecord.SynchronizationInfo.IsSynchronized; foreach (object obj in viewTable) { ViewRecord viewRecord = (ViewRecord)((DictionaryEntry)obj).Value; CollectionView collectionView = viewRecord.View as CollectionView; if (collectionView != null) { collectionView.SetAllowsCrossThreadChanges(isSynchronized); } } } }
private ViewRecord CacheView(object collection, CollectionViewSource cvs, CollectionView cv, ViewRecord vr) { // create the view table, if necessary CollectionRecord cr = this[collection]; ViewTable vt = cr.ViewTable; if (vt == null) { vt = new ViewTable(); cr.ViewTable = vt; // if the collection doesn't implement INCC, it won't hold a strong // reference to its views. To mitigate CollecitonView sorting from being silently // discarded, keep a // strong reference to the ViewTable alive for at least a few // Purge cycles. (See comment at the top of the file.) if (!(collection is INotifyCollectionChanged)) { _inactiveViewTables.Add(vt, InactivityThreshold); } } // keep the view and the view table alive as long as any view // (or the collection itself) is alive if (vr == null) { vr = new ViewRecord(cv); } else if (cv == null) { cv = (CollectionView)vr.View; } cv.SetViewManagerData(vt); // add the view to the table vt[cvs] = vr; return(vr); }
// Token: 0x060076FE RID: 30462 RVA: 0x0021FFC0 File Offset: 0x0021E1C0 private ViewRecord GetExistingView(object collection, CollectionViewSource cvs, Type collectionViewType, Func <object, object> GetSourceItem) { CollectionView collectionView = collection as CollectionView; ViewRecord result; if (collectionView == null) { CollectionRecord collectionRecord = this.EnsureCollectionRecord(collection, GetSourceItem); ViewTable viewTable = collectionRecord.ViewTable; if (viewTable != null) { ViewRecord viewRecord = viewTable[cvs]; if (viewRecord != null) { collectionView = (CollectionView)viewRecord.View; } result = viewRecord; if (this._inactiveViewTables.Contains(viewTable)) { this._inactiveViewTables[viewTable] = 2; } } else { result = null; } } else { result = new ViewRecord(collectionView); } if (collectionView != null) { this.ValidateViewType(collectionView, collectionViewType); } return(result); }
private ViewRecord CacheView(object collection, CollectionViewSource cvs, CollectionView cv, ViewRecord vr) { // create the view table, if necessary ViewTable vt = this[collection]; if (vt == null) { vt = new ViewTable(); Add(collection, vt); // if the collection doesn't implement INCC, it won't hold a strong // reference to its views. To mitigate Dev10 bug 452676, keep a // strong reference to the ViewTable alive for at least a few // Purge cycles. (See comment at the top of the file.) if (!(collection is INotifyCollectionChanged)) { _inactiveViewTables.Add(vt, InactivityThreshold); } } // keep the view and the view table alive as long as any view // (or the collection itself) is alive if (vr == null) vr = new ViewRecord(cv); else if (cv == null) cv = (CollectionView)vr.View; cv.SetViewManagerData(vt); // add the view to the table vt[cvs] = vr; return vr; }
// return an existing view (or null if there isn't one) over the collection private ViewRecord GetExistingView(object collection, CollectionViewSource cvs, Type collectionViewType) { ViewRecord result; CollectionView cv = collection as CollectionView; if (cv == null) { // look up cached entry ViewTable vt = this[collection]; if (vt != null) { ViewRecord vr = vt[cvs]; if (vr != null) { cv = (CollectionView)vr.View; } result = vr; // activity on the VT - reset its expiration date if (_inactiveViewTables.Contains(vt)) { _inactiveViewTables[vt] = InactivityThreshold; } } else { result = null; } } else { // the collection is already a view, just use it directly (no tables needed) result = new ViewRecord(cv); } if (cv != null) { ValidateViewType(cv, collectionViewType); } return result; }
/// <summary> /// Return the object associated with (collection, cvs, type). /// If this is the first reference to this view, add it to the tables. /// </summary> /// <exception cref="ArgumentException"> /// Thrown when the collectionViewType does not implement ICollectionView /// or does not have a constructor that accepts the type of collection. /// Also thrown when the named collection view already exists and is /// not the specified collectionViewType. /// </exception> internal ViewRecord GetViewRecord(object collection, CollectionViewSource cvs, Type collectionViewType, bool createView, Func <object, object> GetSourceItem) { // Order of precendence in acquiring the View: // 0) If collection is already a CollectionView, return it. // 1) If the CollectionView for this collection has been cached, then // return the cached instance. // 2) If a CollectionView derived type has been passed in collectionViewType // create an instance of that Type // 3) If the collection is an ICollectionViewFactory use ICVF.CreateView() // from the collection // 4) If the collection is an IListSource call GetList() and perform 5), // etc. on the returned list // 5) If the collection is an IBindingList return a new BindingListCollectionView // 6) If the collection is an IList return a new ListCollectionView // 7) If the collection is an IEnumerable, return a new CollectionView // (it uses the ListEnumerable wrapper) // 8) return null // An IListSource must share the view with its underlying list. // if the view already exists, just return it // Also, return null if it doesn't exist and we're called in "lazy" mode ViewRecord viewRecord = GetExistingView(collection, cvs, collectionViewType, GetSourceItem); if (viewRecord != null || !createView) { return(viewRecord); } // If the collection is an IListSource, it uses the same view as its // underlying list. IListSource ils = collection as IListSource; IList ilsList = null; if (ils != null) { ilsList = ils.GetList(); viewRecord = GetExistingView(ilsList, cvs, collectionViewType, GetSourceItem); if (viewRecord != null) { return(CacheView(collection, cvs, (CollectionView)viewRecord.View, viewRecord)); } } // Create a new view ICollectionView icv = collection as ICollectionView; if (icv != null) { icv = new CollectionViewProxy(icv); } else if (collectionViewType == null) { // Caller didn't specify a type for the view. ICollectionViewFactory icvf = collection as ICollectionViewFactory; if (icvf != null) { // collection is a view factory - call its factory method icv = icvf.CreateView(); } else { // collection is not a factory - create an appropriate view IList il = (ilsList != null) ? ilsList : collection as IList; if (il != null) { // create a view on an IList or IBindingList IBindingList ibl = il as IBindingList; if (ibl != null) { icv = new BindingListCollectionView(ibl); } else { icv = new ListCollectionView(il); } } else { // collection is not IList, wrap it IEnumerable ie = collection as IEnumerable; if (ie != null) { icv = new EnumerableCollectionView(ie); } } } } else { // caller specified a type for the view. Try to honor it. if (!typeof(ICollectionView).IsAssignableFrom(collectionViewType)) { throw new ArgumentException(SR.Get(SRID.CollectionView_WrongType, collectionViewType.Name)); } // if collection is IListSource, get its list first ( object arg = (ilsList != null) ? ilsList : collection; try { icv = Activator.CreateInstance(collectionViewType, System.Reflection.BindingFlags.CreateInstance, null, new object[1] { arg }, null) as ICollectionView; } catch (MissingMethodException e) { throw new ArgumentException(SR.Get(SRID.CollectionView_ViewTypeInsufficient, collectionViewType.Name, collection.GetType()), e); } } // if we got a view, add it to the tables if (icv != null) { // if the view doesn't derive from CollectionView, create a proxy that does CollectionView cv = icv as CollectionView; if (cv == null) { cv = new CollectionViewProxy(icv); } if (ilsList != null) // IListSource's list shares the same view { viewRecord = CacheView(ilsList, cvs, cv, null); } viewRecord = CacheView(collection, cvs, cv, viewRecord); // raise the event for a new view BindingOperations.OnCollectionViewRegistering(cv); } return(viewRecord); }
// Token: 0x060076F8 RID: 30456 RVA: 0x0021FCC8 File Offset: 0x0021DEC8 internal ViewRecord GetViewRecord(object collection, CollectionViewSource cvs, Type collectionViewType, bool createView, Func <object, object> GetSourceItem) { ViewRecord viewRecord = this.GetExistingView(collection, cvs, collectionViewType, GetSourceItem); if (viewRecord != null || !createView) { return(viewRecord); } IListSource listSource = collection as IListSource; IList list = null; if (listSource != null) { list = listSource.GetList(); viewRecord = this.GetExistingView(list, cvs, collectionViewType, GetSourceItem); if (viewRecord != null) { return(this.CacheView(collection, cvs, (CollectionView)viewRecord.View, viewRecord)); } } ICollectionView collectionView = collection as ICollectionView; if (collectionView != null) { collectionView = new CollectionViewProxy(collectionView); } else if (collectionViewType == null) { ICollectionViewFactory collectionViewFactory = collection as ICollectionViewFactory; if (collectionViewFactory != null) { collectionView = collectionViewFactory.CreateView(); } else { IList list2 = (list != null) ? list : (collection as IList); if (list2 != null) { IBindingList bindingList = list2 as IBindingList; if (bindingList != null) { collectionView = new BindingListCollectionView(bindingList); } else { collectionView = new ListCollectionView(list2); } } else { IEnumerable enumerable = collection as IEnumerable; if (enumerable != null) { collectionView = new EnumerableCollectionView(enumerable); } } } } else { if (!typeof(ICollectionView).IsAssignableFrom(collectionViewType)) { throw new ArgumentException(SR.Get("CollectionView_WrongType", new object[] { collectionViewType.Name })); } object obj = (list != null) ? list : collection; try { collectionView = (Activator.CreateInstance(collectionViewType, BindingFlags.CreateInstance, null, new object[] { obj }, null) as ICollectionView); } catch (MissingMethodException innerException) { throw new ArgumentException(SR.Get("CollectionView_ViewTypeInsufficient", new object[] { collectionViewType.Name, collection.GetType() }), innerException); } } if (collectionView != null) { CollectionView collectionView2 = collectionView as CollectionView; if (collectionView2 == null) { collectionView2 = new CollectionViewProxy(collectionView); } if (list != null) { viewRecord = this.CacheView(list, cvs, collectionView2, null); } viewRecord = this.CacheView(collection, cvs, collectionView2, viewRecord); BindingOperations.OnCollectionViewRegistering(collectionView2); } return(viewRecord); }