예제 #1
0
        // If an already invalid child is set or the previous child was invalid,
        // the aggregated validation state of the owner changes, therefore an
        // ValidationResultChanged event should be raised.
        private void DetectValidationResultChange(IBehaviorContext context, Action action)
        {
            IViewModel oldChild = this.GetValueNext <TValue>(context);

            action();

            IViewModel newChild = this.GetValueNext <TValue>(context);

            // It is important to query the 'oldResult' after executing the 'action'. The
            // following scenario could happen otherwise:
            //   1. 'oldResult' is assigned before the action and is valid.
            //   2. The action is executed and makes 'oldChild' invalid and 'newChild'
            //      stays valid. Since 'oldChild' is still in the hierarchy at this
            //      time, the error is propagated to the validation caches of the
            //      parent.
            //   3. 'newResult' is assigned to result of the 'newChild' (valid).
            //   4. We would not detect a change in the 'if' below and therefore not
            //      raise a change which would leave the validation cache of the parents
            //      with the stale error.
            ValidationResult oldResult = GetValidationResultOrValidIfNull(oldChild);
            ValidationResult newResult = GetValidationResultOrValidIfNull(newChild);

            if (!Object.Equals(oldResult, newResult))
            {
                context.NotifyChange(ChangeArgs.ValidationResultChanged());
            }
        }
        public void HandleChange(IBehaviorContext context, CollectionChangedArgs <TItemVM> args)
        {
            var c = args.Collection;

            var oldItems = (IEnumerable <IViewModel>)args.OldItems;
            var newItems = (IEnumerable <IViewModel>)args.NewItems;

            ChangeArgs a;

            switch (args.Type)
            {
            // No change of 'ItemsRemoved' is raised to give the client a chance
            // to distinguish if the removal was due to a repopulation (Type =
            // 'Populated' and 'OldItems' contains items) or if the removal was
            // triggered by a 'Clear', 'Remove' or 'SetItem'.
            case CollectionChangeType.Populated:
                a = ChangeArgs.CollectionPopulated(c, oldItems, args.Reason);
                context.NotifyChange(a);
                break;
            }

            switch (args.Type)
            {
            case CollectionChangeType.ItemRemoved:
            case CollectionChangeType.ItemSet:
            case CollectionChangeType.ItemsCleared:
                if (args.OldItems.Any())
                {
                    a = ChangeArgs.ItemsRemoved(c, oldItems, args.Reason);
                    context.NotifyChange(a);
                }
                break;
            }

            switch (args.Type)
            {
            case CollectionChangeType.ItemAdded:
            case CollectionChangeType.ItemSet:
                a = ChangeArgs.ItemsAdded(c, newItems, args.Reason);
                context.NotifyChange(a);
                break;
            }

            this.HandleChangeNext(context, args);
        }
        public virtual void NotifyPropertyChanged(IBehaviorContext context, ValueStage stage, TValue oldValue, TValue newValue)
        {
            var args = ChangeArgs.PropertyChanged(
                _property, stage,
                reason: null
                );

            context.NotifyChange(args);

            this.NotifyPropertyChangedNext(context, stage, oldValue, newValue);
        }
예제 #4
0
        public void Refresh(IBehaviorContext context, RefreshOptions options)
        {
            context.NotifyChange(
                ChangeArgs.PropertyChanged(
                    _property,
                    ValueStage.ValidatedValue,
                    RefreshReason.Create(options.ExecuteRefreshDependencies)
                    )
                );

            this.RefreshNext(context, options);
        }
예제 #5
0
        public override void NotifyPropertyChanged(IBehaviorContext context, ValueStage stage, TValue oldValue, TValue newValue)
        {
            var args = ChangeArgs.ViewModelPropertyChanged(
                _property,
                stage,
                oldValue,
                newValue,
                reason: null
                );

            context.NotifyChange(args);
        }
예제 #6
0
        public void NotifyChange_CallsNotifyChangeOfViewModelWithPrependedViewModel()
        {
            var vm = ViewModelStub.Build();

            var args = CreateChangeArgs();
            IBehaviorContext kernel = CreateKernel(vm);

            kernel.NotifyChange(args);

            var expectedArgs = args.PrependViewModel(vm);

            DomainAssert.AreEqual(expectedArgs, vm.NotifyChangeInvocations.SingleOrDefault());
        }
예제 #7
0
        public void UpdateValidationResult(IBehaviorContext context, ValidationResult result)
        {
            var previousResult = GetValidationResult(context);

            if (!result.Equals(previousResult))
            {
                SetOrClearValidationResult(context, result);

                var args = _property != null?
                           ChangeArgs.ValidationResultChanged(_property, _stage) :
                               ChangeArgs.ValidationResultChanged();

                context.NotifyChange(args);
            }
        }
예제 #8
0
        public void HandleChange(IBehaviorContext context, CollectionChangedArgs <TItemVM> args)
        {
            IEnumerable <TItemVM> changedItems = args
                                                 .OldItems
                                                 .Concat(args.NewItems);

            IEnumerable <ValidationResult> changedItemsResults = changedItems
                                                                 .Select(x => x.Kernel.GetValidationResult());

            var changedItemsResult = ValidationResult.Join(changedItemsResults);

            this.HandleChangeNext(context, args);

            // If already invalid items are added or removed, the aggregated
            // validation state of the collection owner changes, therefore an
            // ValidationResultChanged event should be raised.
            if (!changedItemsResult.IsValid)
            {
                context.NotifyChange(ChangeArgs.ValidationResultChanged(args.Reason));
            }
        }
예제 #9
0
        public void NotifyChange_CallsParentWithExtendedPath()
        {
            var parentVM = ViewModelStub.Build();
            var vm       = ViewModelStub.Build();


            var parentKernel = CreateKernel(parentVM);
            var kernel       = CreateKernel(vm);

            kernel.Parents.Add(parentVM);

            IBehaviorContext kernelContext = kernel;

            var args = CreateChangeArgs();

            kernelContext.NotifyChange(args);

            var expectedArgs = args
                               .PrependViewModel(vm)
                               .PrependViewModel(parentVM);

            DomainAssert.AreEqual(expectedArgs, parentVM.NotifyChangeInvocations.SingleOrDefault());
        }
예제 #10
0
        public override void InitializeValue(IBehaviorContext context)
        {
            base.InitializeValue(context);

            TValue childVM = this.GetValueNext <TValue>(context);

            if (childVM != null)
            {
                ValidationResult childValidatonResult = childVM
                                                        .Kernel
                                                        .GetValidationResult();

                if (!childValidatonResult.IsValid)
                {
                    // If 'PopulatedWith' returns an already invalid item, the aggregated
                    // validation state of the collection owner changes, therefore an
                    // 'ValidationResultChanged' event should be raised.
                    if (!childValidatonResult.IsValid)
                    {
                        context.NotifyChange(ChangeArgs.ValidationResultChanged());
                    }
                }
            }
        }
예제 #11
0
        public void Refresh(IBehaviorContext context, RefreshOptions options)
        {
            RequireInitialized();

            var previousValue = GetValue(context);

            RefreshCache(context);
            var newValue = GetValue(context);

            if (!Object.Equals(newValue, previousValue))
            {
                var args = ChangeArgs.ViewModelPropertyChanged(
                    _property,
                    ValueStage.ValidatedValue,
                    previousValue,
                    newValue,
                    RefreshReason.Create(options.ExecuteRefreshDependencies)
                    );

                context.NotifyChange(args);
            }

            this.RefreshNext(context, options);
        }
 public void NotifyChange(ChangeArgs args)
 {
     Check.NotNull(args, nameof(args));
     _inner.NotifyChange(args);
     NotifyChangeInvocations.Add(args);
 }