public ObjectPropertyAtom(IObjectInstance objectInstance, ClassProperty classProperty, bool hasChildObject) : base(objectInstance, classProperty) { _hasChildObject = hasChildObject; if (ClassProperty.CanRead) { // When the property is out of date, update it from the wrapped object. _depProperty = new Computed(delegate { object value = ClassProperty.GetObjectValue(ObjectInstance.WrappedObject); if (_hasChildObject) { IObjectInstance oldChild = _child; object oldValue = oldChild == null ? null : oldChild.WrappedObject; _child = null; IObjectInstance wrapper; if (value == null) { wrapper = null; } else if (value == oldValue) { wrapper = oldChild; _child = wrapper; } else { if (WrapObject(value, out wrapper)) { _child = wrapper; } } ClassProperty.SetUserOutput(ObjectInstance, wrapper); if (oldChild != _child && oldChild != null) { ObjectInstance.Tree.RemoveKey(oldValue); oldChild.Dispose(); } } else { ClassProperty.SetUserOutput(ObjectInstance, value); } }); } }
private void OnUpdateCollection() { IEnumerable values = ClassProperty.GetObjectValue(ObjectInstance.WrappedObject) as IEnumerable; List <object> newCollection; if (_hasChildObjects) { List <IObjectInstance> oldChildren = new List <IObjectInstance>(_children); Dictionary <object, IObjectInstance> oldValues = oldChildren.ToDictionary(wrapper => wrapper.WrappedObject); // Get the source collection from the wrapped object. _children.Clear(); newCollection = new List <object>(); foreach (object value in values) { IObjectInstance wrapper; if (oldValues.TryGetValue(value, out wrapper)) { _children.Add(wrapper); newCollection.Add(wrapper); } else { if (WrapObject(value, out wrapper)) { _children.Add(wrapper); } newCollection.Add(wrapper); } } foreach (IObjectInstance child in oldChildren.Except(_children)) { ObjectInstance.Tree.RemoveKey(child.WrappedObject); child.Dispose(); } } else { newCollection = values.OfType <object>().ToList(); } AssignToObservableCollection(newCollection); }
private void OnUpdateCollection() { // Get the source collection from the wrapped object. IEnumerable source = ClassProperty.GetObjectValue(ObjectInstance.WrappedObject) as IEnumerable; List <object> sourceCollection = source.OfType <object>().ToList(); // Delay the update to the observable collection so that we don't record dependencies on // properties used in the items template. XAML will invoke the item template synchronously // as we add items to the observable collection, thus causing other view model property // getters to fire. _delay = delegate { // Create a list of new items. List <CollectionItem> items = new List <CollectionItem>(); // Dump all previous items into a recycle bin. using (RecycleBin <CollectionItem> bin = new RecycleBin <CollectionItem>()) { foreach (object oldItem in _collection) { bin.AddObject(new CollectionItem(_collection, oldItem, true)); } // Add new objects to the list. if (sourceCollection != null) { foreach (object obj in sourceCollection) { items.Add(bin.Extract(new CollectionItem(_collection, TranslateOutgoingValue(obj), false))); } } // All deleted items are removed from the collection at this point. } // Ensure that all items are added to the list. int index = 0; foreach (CollectionItem item in items) { item.EnsureInCollection(index); ++index; } }; }
public ObjectPropertyAtom(IObjectInstance objectInstance, ClassProperty classProperty) : base(objectInstance, classProperty) { if (ClassProperty.CanRead) { // When the property is out of date, update it from the wrapped object. _depProperty = new Computed(delegate { object value = ClassProperty.GetObjectValue(ObjectInstance.WrappedObject); value = TranslateOutgoingValue(value); if (!Object.Equals(_value, value)) { _value = value; } if (_firePropertyChanged) { ObjectInstance.FirePropertyChanged(ClassProperty.Name); } _firePropertyChanged = true; }); // When the property becomes out of date, trigger an update. _depProperty.Invalidated += () => UpdateScheduler.ScheduleUpdate(UpdateNow); } }