public void SetItems_ListChangedIsRaisedAfterBehaviors()
        {
            var actionLog = new StringBuilder();

            var changeListener = new TestChangeListener();

            var ownerProperty = PropertyStub
                                .WithBehaviors(changeListener)
                                .Build();

            var ownerVM = ViewModelStub
                          .WithProperties(ownerProperty)
                          .Build();

            var collection = new VMCollection <IViewModel>(ownerVM, ownerProperty);

            changeListener.HandleChange += delegate {
                actionLog.Append("ChangeHandlerBehavior ");
            };

            collection.ListChanged += delegate {
                actionLog.Append("ListChanged ");
            };

            IVMCollection <IViewModel> c = collection;

            c.ReplaceItems(new[] { ViewModelStub.Build(), ViewModelStub.Build() }, null);

            Assert.AreEqual("ChangeHandlerBehavior ListChanged ", actionLog.ToString());
        }
示例#2
0
 public static IVMDescriptor GetItemDescriptor(this IVMCollection collection)
 {
     return(collection
            .OwnerProperty
            .Behaviors
            .GetItemDescriptor());
 }
示例#3
0
        public override PathMatch Matches(PathDefinitionIterator definitionSteps, PathIterator step)
        {
            if (!step.HasStep || !step.IsCollection)
            {
                return(PathMatch.Fail());
            }

            IVMCollection parentCollection = step.Collection;

            step.MoveNext();

            if (!step.HasStep || !step.IsProperty)
            {
                return(PathMatch.Fail());
            }

            if (!(parentCollection.GetItemDescriptor() is TDescriptor))
            {
                return(PathMatch.Fail());
            }

            var itemDescriptor   = parentCollection.GetItemDescriptor();
            var expectedProperty = _propertySelector.GetProperty(itemDescriptor);

            if (expectedProperty == step.Property)
            {
                PathMatch result     = PathMatch.Succeed(length: 1);
                PathMatch nextResult = definitionSteps.MatchesNext(step);

                return(PathMatch.Combine(result, nextResult));
            }

            return(PathMatch.Fail());
        }
示例#4
0
        private void ExpectCollectionPropertyValidationOf(IVMCollection <ItemVM> collection)
        {
            IViewModel owner;
            string     key;

            if (collection == OwnerOfAB.CollectionA)
            {
                owner = OwnerOfAB;
                key   = CollectionAValidatorKey;
            }
            else if (collection == OwnerOfAB.CollectionB)
            {
                owner = OwnerOfAB;
                key   = CollectionBValidatorKey;
            }
            else if (collection == OwnerOfC.CollectionC)
            {
                owner = OwnerOfC;
                key   = CollectionCValidatorKey;
            }
            else
            {
                throw new InternalTestFailureException();
            }

            Results.ExpectInvocationOf.CollectionPropertyValidation
            .Targeting(collection, x => x.ItemProperty)
            .On(owner, key);
        }
 public IValidatorInvocationBuilder Targeting <TDescriptor>(
     IVMCollectionExpression <IViewModel <TDescriptor> > target,
     Func <TDescriptor, IVMPropertyDescriptor> targetPropertySelector
     ) where TDescriptor : IVMDescriptor
 {
     _targetCollection = (IVMCollection)target;
     _targetProperty   = targetPropertySelector((TDescriptor)_targetCollection.GetItemDescriptor());
     return(this);
 }
示例#6
0
        public void Matches_WithNonMatchingCollectionPlusProperty_Fails()
        {
            IVMCollection <EmployeeVM> nonMatching = VM.GetValue(x => x.Managers);

            AssertNoMatch(
                CreateStep((ProjectVMDescriptor x) => x.Name),
                Path.Empty.Prepend(ProjectVM.ClassDescriptor.Name).Prepend(nonMatching)
                );
        }
        private void Repopulate(IBehaviorContext context, IVMCollection <TItemVM> collection, IChangeReason reason)
        {
            var sourceItems = GetSourceItems(context);

            IEnumerable <TItemVM> newItems = sourceItems
                                             .Select(s => CreateAndInitializeItem(context, s));

            collection.ReplaceItems(newItems, reason);
        }
        private void Repopulate(IBehaviorContext context, IVMCollection <TItemVM> collection, IChangeReason reason)
        {
            var sourceItems = this.GetValueNext <IEnumerable <TItemSource> >(context);

            var items = sourceItems
                        .Select(sourceItem => GetItemVM(context, sourceItem));

            collection.ReplaceItems(items, reason);
        }
示例#9
0
 public CollectionValidationArgs(
     IValidator validator,
     TOwnerVM owner,
     IVMCollection <TItemVM> items
     )
     : base(ValidationStep.ViewModel, validator, owner)
 {
     Check.NotNull(items, nameof(items));
     Items = items;
 }
示例#10
0
        public void Matches_WithMatchingCollectionPlusProperty_Fails()
        {
            // Use CollectionPropertyStep for this scenario (only relevant for validation target).
            IVMCollection <ProjectVM> collection = VM.GetValue(x => x.Projects);

            AssertNoMatch(
                CreateStep((ProjectVMDescriptor x) => x.Name),
                Path.Empty.Prepend(ProjectVM.ClassDescriptor.Name).Prepend(collection)
                );
        }
        public void Refresh(IBehaviorContext context, RefreshOptions options)
        {
            // Call next behavior first, because a source accessor behavior may handle
            // it.
            this.RefreshNext(context, options);
            _collectionSourceCache.Clear(context);

            // ToArray so that (1) source is only enumerated once and (2) acess by index
            // (required by the equality check) is guaranteed to be fast.
            TItemSource[]           newSourceItems = GetSourceItems(context).ToArray();
            IVMCollection <TItemVM> vmCollection   = GetValue(context);

            IEnumerable <TItemVM> itemsToRefresh = Enumerable.Empty <TItemVM>();

            if (AreCollectionContentsEqual(vmCollection, newSourceItems))
            {
                itemsToRefresh = vmCollection;
            }
            else
            {
                Dictionary <TItemSource, TItemVM> previousItemsBySource = vmCollection.ToDictionary(
                    x => x.Source,
                    _reusabilitySourceComparer
                    );

                List <TItemVM> newItems    = new List <TItemVM>();
                List <TItemVM> reusedItems = new List <TItemVM>();

                foreach (TItemSource s in newSourceItems)
                {
                    TItemVM item;
                    bool    isReusedItem = previousItemsBySource.TryGetValue(s, out item);

                    if (isReusedItem)
                    {
                        reusedItems.Add(item);
                    }
                    else
                    {
                        item = CreateAndInitializeItem(context, s);
                    }

                    newItems.Add(item);
                }

                vmCollection.ReplaceItems(newItems, RefreshReason.Create(options.ExecuteRefreshDependencies));
                itemsToRefresh = reusedItems;
            }

            if (options.Scope.HasFlag(RefreshScope.Content))
            {
                itemsToRefresh
                .ForEach(x => x.Kernel.RefreshWithoutValidation(options.ExecuteRefreshDependencies));
            }
        }
        public void Refresh(IBehaviorContext context, RefreshOptions options)
        {
            this.RefreshNext(context, options);

            IVMCollection <TItemVM> selectedItems = this.GetValueNext <IVMCollection <TItemVM> >(context);

            foreach (TItemVM item in selectedItems)
            {
                item.Kernel.Refresh();
            }
        }
 public static ICollectionValidationTarget ForCollection(
     ValidationStep step,
     IVMCollection collection,
     IVMPropertyDescriptor property = null
     )
 {
     Check.NotNull(collection, nameof(collection));
     return(new ValidationTarget(step)
     {
         Collection = collection, Property = property
     });
 }
示例#14
0
 internal static PathHelperResult Succeeded(
     IViewModel vm = null,
     IVMPropertyDescriptor property = null,
     IVMCollection collection       = null
     )
 {
     return(new PathHelperResult {
         Success = true,
         VM = vm,
         Property = property,
         Collection = collection
     });
 }
        public static CollectionChangedArgs <TItemVM> CollectionCleared(
            IVMCollection <TItemVM> collection,
            TItemVM[] oldItems
            )
        {
            Check.NotNull(collection, nameof(collection));
            Check.NotNull(oldItems, nameof(oldItems));

            return(new CollectionChangedArgs <TItemVM>(
                       CollectionChangeType.ItemsCleared,
                       collection,
                       oldItems: oldItems
                       ));
        }
 private CollectionChangedArgs(
     CollectionChangeType type,
     IVMCollection <TItemVM> collection,
     IEnumerable <TItemVM> oldItems = null,
     IEnumerable <TItemVM> newItems = null,
     IChangeReason reason           = null
     )
 {
     Type       = type;
     Collection = collection;
     Index      = -1;
     OldItems   = oldItems ?? Enumerable.Empty <TItemVM>();
     NewItems   = newItems ?? Enumerable.Empty <TItemVM>();
     Reason     = reason;
 }
        public static IValidationErrorTarget ForError(
            ValidationStep step,
            IViewModel vm,
            IVMCollection collection       = null,
            IVMPropertyDescriptor property = null
            )
        {
            Check.NotNull(vm, nameof(vm));

            return(new ValidationTarget(step)
            {
                VM = vm,
                Collection = collection,
                Property = property
            });
        }
        /// <inheritdoc />
        public void SetDisplayValue(IBehaviorContext vm, object value)
        {
            Check.NotNull(vm, nameof(vm));

            IEnumerable <TItemVM> sourceCollection = null;

            if (value != null)
            {
                IEnumerable untypedSourceCollection = (IEnumerable)value;
                sourceCollection = untypedSourceCollection.Cast <TItemVM>();
            }

            IVMCollection <TItemVM> targetCollection = GetTargetCollection(vm);

            SynchronizeCollections(sourceCollection, targetCollection);
        }
 private CollectionChangedArgs(
     CollectionChangeType type,
     IVMCollection <TItemVM> collection,
     int index,
     TItemVM oldItem = default(TItemVM),
     TItemVM newItem = default(TItemVM)
     )
 {
     Type       = type;
     Collection = collection;
     Index      = index;
     OldItem    = oldItem;
     OldItems   = oldItem != null ? new[] { oldItem } : Enumerable.Empty <TItemVM>();
     NewItem    = newItem;
     NewItems   = newItem != null ? new[] { newItem } : Enumerable.Empty <TItemVM>();
 }
 public ValidatorInvocation(
     ValidatorType type,
     IViewModel owner,
     IViewModel targetVM,
     IVMCollection targetCollection,
     IVMPropertyDescriptor targetProperty,
     object validatorKey = null
     )
 {
     Type             = type;
     Owner            = owner;
     TargetVM         = targetVM;
     TargetProperty   = targetProperty;
     TargetCollection = targetCollection;
     ValidatorKey     = validatorKey;
 }
        public static CollectionChangedArgs <TItemVM> ItemInserted(
            IVMCollection <TItemVM> collection,
            TItemVM newItem,
            int index
            )
        {
            Check.NotNull(collection, nameof(collection));
            Check.NotNull(newItem, nameof(newItem));
            Check.Requires(0 <= index && index < collection.Count);

            return(new CollectionChangedArgs <TItemVM>(
                       CollectionChangeType.ItemAdded,
                       collection,
                       index,
                       newItem: newItem
                       ));
        }
        public static CollectionChangedArgs <TItemVM> CollectionPopulated(
            IVMCollection <TItemVM> collection,
            TItemVM[] oldItems,
            IChangeReason reason = null
            )
        {
            Check.NotNull(collection, nameof(collection));
            Check.NotNull(oldItems, nameof(oldItems));

            return(new CollectionChangedArgs <TItemVM>(
                       CollectionChangeType.Populated,
                       collection,
                       oldItems: oldItems,
                       newItems: collection,
                       reason: reason
                       ));
        }
        public static CollectionChangedArgs <TItemVM> ItemRemoved(
            IVMCollection <TItemVM> collection,
            TItemVM oldItem,
            int index
            )
        {
            Check.NotNull(collection, nameof(collection));
            Check.NotNull(oldItem, nameof(oldItem));
            Check.Requires(0 <= index && index <= collection.Count);

            return(new CollectionChangedArgs <TItemVM>(
                       CollectionChangeType.ItemRemoved,
                       collection,
                       index,
                       oldItem: oldItem
                       ));
        }
        public void ReplaceItems_CallsHandleChangeWithCollectionPopulatedArgs()
        {
            var oldItems = new[] { CreateItem(), CreateItem() };
            var newItems = new[] { CreateItem() };

            Collection.Add(oldItems[0]);
            Collection.Add(oldItems[1]);

            ResetStub();
            IVMCollection <IViewModel> c = Collection;

            c.ReplaceItems(newItems, null);

            AssertChangeArgs(
                CollectionChangedArgs <IViewModel> .CollectionPopulated(Collection, oldItems)
                );
        }
示例#25
0
        internal static ChangeArgs ItemsAdded(
            IVMCollection collection,
            IEnumerable <IViewModel> newItems,
            IChangeReason reason = null
            )
        {
            Check.NotNull(collection, nameof(collection));
            Check.NotNull(newItems, nameof(newItems));
            Check.NotEmpty(newItems, nameof(newItems));

            return(new ChangeArgs(
                       ChangeType.AddedToCollection,
                       ValueStage.ValidatedValue,
                       Path.Empty.Append(collection),
                       newItems: newItems,
                       reason: reason
                       ));
        }
示例#26
0
        internal static ChangeArgs ItemsRemoved(
            IVMCollection collection,
            IEnumerable <IViewModel> oldItems,
            IChangeReason reason = null
            )
        {
            Check.NotNull(collection, nameof(collection));
            Check.NotNull(oldItems, nameof(oldItems));
            Check.NotEmpty(oldItems, nameof(oldItems));

            return(new ChangeArgs(
                       ChangeType.RemovedFromCollection,
                       ValueStage.ValidatedValue,
                       Path.Empty.Append(collection),
                       oldItems: oldItems,
                       reason: reason
                       ));
        }
示例#27
0
        private bool Matches(IVMCollection collection, PathIterator nextStep)
        {
            bool canMatchAgainstItemDescriptor = nextStep.IsProperty;

            if (!canMatchAgainstItemDescriptor)
            {
                return(false);
            }

            if (!(collection.GetItemDescriptor() is TDescriptor))
            {
                return(false);
            }

            TDescriptor itemDescriptor = (TDescriptor)collection.GetItemDescriptor();

            return(_propertySelector.GetProperty(itemDescriptor) == nextStep.Property);
        }
示例#28
0
        internal static ChangeArgs CollectionPopulated(
            IVMCollection collection,
            IEnumerable <IViewModel> oldItems,
            IChangeReason reason = null
            )
        {
            Check.NotNull(collection, nameof(collection));

            var newItems = (IEnumerable <IViewModel>)collection;

            return(new ChangeArgs(
                       ChangeType.CollectionPopulated,
                       ValueStage.ValidatedValue,
                       Path.Empty.Append(collection),
                       newItems: newItems,
                       oldItems: oldItems,
                       reason: reason
                       ));
        }
        private bool AreCollectionContentsEqual(
            IVMCollection <TItemVM> vmCollection,
            TItemSource[] sourceCollection
            )
        {
            if (sourceCollection.Length != vmCollection.Count)
            {
                return(false);
            }

            for (int i = 0; i < sourceCollection.Length; i++)
            {
                if (!_reusabilitySourceComparer.Equals(sourceCollection[i], vmCollection[i].Source))
                {
                    return(false);
                }
            }

            return(true);
        }
示例#30
0
        private static bool CollectionIsFollowedByItemViewModel(PathIterator step)
        {
            if (!step.IsCollection)
            {
                return(false);
            }

            IVMCollection collection = step.Collection;

            step.MoveNext();

            if (!step.HasStep || !step.IsViewModel)
            {
                return(false);
            }

            IViewModel potentialItem = step.ViewModel;

            return(potentialItem.Kernel.OwnerCollections.Any(x => x.Equals(collection)));
        }