private void AdapterCreationCallback(TSourceEnumerationItem sourceValue) { try { //Replace item with a newly created adapter var OldItem = this.items.First(_ => object.Equals(_.SourceValue, sourceValue)); ObservableExpressionFactory.EventSink EventSink = new ObservableExpressionFactory.EventSink((sender, e) => this.AdapterCreationCallback(sourceValue)); CachedValueCollectionItem NewItem = new CachedValueCollectionItem(sourceValue, this.adapter.adapterCreation(this.source, sourceValue, EventSink), EventSink); this.Replace(OldItem, NewItem); } catch (Exception) { // Something happend while converting and/or adding the item. Reset the colleciton and retry 'from scratch' this.adapter.NotifyItemUpdateFailed(this.source); } }
public CachedValueCollectionItem(TSourceEnumerationItem sourceValue, TTargetEnumerationItem targetValue, ObservableExpressionFactory.EventSink eventSink) { this.eventSink = eventSink; this.SourceValue = sourceValue; this.TargetValue = targetValue; }
public void Update(IEnumerable <TSourceEnumerationItem> values) { TSourceEnumerationItem[] Values = values != null?values.ToArray() : new TSourceEnumerationItem[0]; if (Values.Length > 0) { //First delete items to avoid unneeded move operations. save in arraqy to be able to modify the source collection foreach (CachedValueCollectionItem ItemToDelete in this.items.Where(item => Values.Any(value => object.Equals(value, item.SourceValue)) == false).ToArray()) { this.Remove(ItemToDelete); } ObservableCollection <CachedValueCollectionItem> OldValues = new ObservableCollection <CachedValueCollectionItem>(this.items.ToArray()); //Move existing entries to new locations and eventually add new entries for (int Index = 0; Index < Values.Length; Index++) { if (OldValues.Count > Index && object.Equals(OldValues[Index], Values[Index])) { //Item is still the same -> nothing to do DebugLogger.WriteLine(this, LoggingLevel.Verbose, () => $"Collection Update: index {Index} stays unchanged"); } else { //Search for the item. first we have to find the item in the cache to get the index. Skip already sorted entries to allow handling of equal objects in the same list int SearchIndex = OldValues.IndexOf(OldValues.Skip(Index).FirstOrDefault(_ => object.Equals(_.SourceValue, Values[Index]))); if (SearchIndex != -1) { //Found in the list if (Index != SearchIndex) { //-> move to front DebugLogger.WriteLine(this, LoggingLevel.Verbose, () => $"Collection Update: Move index {SearchIndex} to index {Index}"); this.Move(SearchIndex, Index); OldValues.Move(SearchIndex, Index); } else { //Position already matches -> do nothing } } else { //Not found -> must be new DebugLogger.WriteLine(this, LoggingLevel.Verbose, () => $"Collection Update: Add new item at index {Index}"); TSourceEnumerationItem SourceValue = Values[Index]; ObservableExpressionFactory.EventSink EventSink = new ObservableExpressionFactory.EventSink((sender, e) => this.AdapterCreationCallback(SourceValue)); CachedValueCollectionItem NewItem = new CachedValueCollectionItem(SourceValue, this.adapter.adapterCreation(this.source, SourceValue, EventSink), EventSink); this.Insert(Index, NewItem); OldValues.Insert(Index, NewItem); } } } } else { this.ClearItems(); } }