Example #1
0
        /// <summary>
        /// Merges a collection of view models with a list of models
        /// </summary>
        public static void MergeCollection <TViewModel, TModel>(
            this ICollection <TViewModel> collection,
            IReadOnlyList <TModel> updated,
            IMergeStrategy <TModel, TViewModel> strategy)
            where TViewModel : IIdentifiableObject
            where TModel : IIdentifiableObject
        {
            // Remove those without id or not existing in the updated collection
            var removed = collection.Where(r => r.Id == 0 || updated.All(u => u.Id != r.Id)).ToList();

            foreach (var obj in removed)
            {
                collection.Remove(obj);
            }

            foreach (var updatedModel in updated)
            {
                var match = collection.FirstOrDefault(r => r.Id == updatedModel.Id);
                if (match != null)
                {
                    strategy.UpdateModel(match, updatedModel);
                }
                else
                {
                    var vm = strategy.FromModel(updatedModel);
                    collection.Add(vm);
                }
            }
        }
Example #2
0
        /// <summary>
        /// Merge a recursive model structure into an existing observable view model structure
        /// </summary>
        public static void MergeTree <TModel>(
            this Collection <TreeItemViewModel> current,
            IReadOnlyList <TModel> updated,
            IMergeStrategy <TModel, TreeItemViewModel> strategy)
            where TModel : class, ITreeItemModel <TModel>
        {
            // Use 'for'-loop, because it is modification tolerant
            int currentIndex = 0, updatedIndex = 0;

            while (currentIndex < current.Count || updatedIndex < updated.Count)
            {
                var currentItem = GetItem(current, currentIndex);
                var updatedItem = GetItem(updated, updatedIndex);
                // Default: Update the model if it matches
                if (currentItem != null && currentItem.Id == updatedItem?.Id)
                {
                    strategy.UpdateModel(currentItem, updatedItem);
                    currentIndex++;
                    updatedIndex++;
                    MergeTree(currentItem.Children, updatedItem.Children, strategy);
                }
                // Item was appended or inserted
                else if (currentItem == null || HasId(updated, currentItem.Id, updatedIndex))
                {
                    currentItem = strategy.FromModel(updatedItem);
                    current.Insert(currentIndex, currentItem);
                    currentIndex++;
                    updatedIndex++;
                    MergeTree(currentItem.Children, updatedItem.Children, strategy);
                }
                // In any other case: Remove
                else
                {
                    current.RemoveAt(currentIndex);
                    updatedIndex++;
                }
            }
        }