// 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); }
public void Refresh(IBehaviorContext context, RefreshOptions options) { context.NotifyChange( ChangeArgs.PropertyChanged( _property, ValueStage.ValidatedValue, RefreshReason.Create(options.ExecuteRefreshDependencies) ) ); this.RefreshNext(context, options); }
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); }
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()); }
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); } }
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)); } }
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()); }
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()); } } } }
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); }