Esempio n. 1
0
        protected virtual void Dispose(bool disposing)
        {
            if (!_disposedValue)
            {
                if (disposing)
                {
                    // TODO: dispose managed state (managed objects)
                    if (_control != null)
                    {
                        _control.DataContextChanged -= Control_DataContextChanged;
                        _control.TryDispose();
                        _control = null;
                    }

                    if (_viewModel != null)
                    {
                        _viewModel.ErrorsChanged -= NotifyDataErrorInfo_ErrorsChanged;
                        _viewModel = null;
                    }

                    if (_errorPopup != null)
                    {
                        _errorPopup.TryDispose();
                        _errorPopup = null;
                    }
                }

                // TODO: free unmanaged resources (unmanaged objects) and override finalizer
                // TODO: set large fields to null
                _disposedValue = true;
            }
        }
Esempio n. 2
0
 internal WeakErrorsChangedListener(INotifyDataErrorInfo notifyDataErrorInfo, bool notifyChild, IErrorsChangedListener errorsChangedListener)
 {
     this.notifyDataErrorInfo           = notifyDataErrorInfo;
     this.notifyChild                   = notifyChild;
     notifyDataErrorInfo.ErrorsChanged += new EventHandler <DataErrorsChangedEventArgs>(this.ErrorsChangedCallback);
     this.weakErrorsChangedListener     = new WeakReference(errorsChangedListener);
 }
Esempio n. 3
0
        private void UpdateErrors(INotifyDataErrorInfo newViewModel)
        {
            if (_errorsGrid == null || _errorList == null || _title == null)
            {
                return;
            }

            if (newViewModel == null)
            {
                return;
            }

            var allErrors = newViewModel.GetErrors(ValidatingBase.AllErrorsToken).Cast <string>();

            if (allErrors.Any())
            {
                this.Log().Debug($"We have errors - {allErrors.Count()}");

                _errorsGrid.Visibility = Visibility.Visible;
                _title.Text            = $"{allErrors.Count()} error{(allErrors.Count() > 1 ? "s" : "")}";
                _boundErrors.Clear();
                foreach (var error in allErrors)
                {
                    _boundErrors.Add(error);
                }
            }
            else
            {
                _errorsGrid.Visibility = Visibility.Collapsed;
            }
        }
        private static void UpdateValidationContent(string propertyName, INotifyDataErrorInfo context, ContentControl validationPlaceholder)
        {
            IEnumerable <string> errors = context.GetErrors(propertyName).OfType <string>();

            validationPlaceholder.Content    = errors;
            validationPlaceholder.Visibility = errors.Any() ? Visibility.Visible : Visibility.Collapsed;
        }
        public void ValidateMethodShouldCallNotifyEvent()
        {
            ThreadManager.ImmediateInvokeAsync           = true;
            ThreadManager.ImmediateInvokeOnUiThreadAsync = true;
            ThreadManager.ImmediateInvokeOnUiThread      = true;

            int countInvoke = 0;
            ValidatableViewModel viewModel       = GetValidatableViewModel();
            INotifyDataErrorInfo notifyDataError = viewModel;

            notifyDataError.ErrorsChanged += (sender, args) =>
            {
                args.PropertyName.ShouldEqual(PropToValidate1);
                countInvoke++;
            };
            var validator = viewModel.AddValidator <SpyValidator>(new object());

            notifyDataError.HasErrors.ShouldBeFalse();
            validator.SetErrors(PropToValidate1, PropToValidate1);
            countInvoke.ShouldEqual(1);
            validator.SetErrors(PropToValidate1, PropToValidate2);
            countInvoke.ShouldEqual(2);
            notifyDataError.HasErrors.ShouldBeTrue();

            //NOTE: Event is not invoked, if errors is not changed.

            /*viewModel.ValidateAsync(PropToValidate1);
             * countInvoke.ShouldEqual(2);*/
        }
Esempio n. 6
0
        public void ImplementsINotifyDataErrorInfo()
        {
            TestViewModel        viewModel = GivenViewModel();
            INotifyDataErrorInfo notify    = GivenNotifyDataErrorInfo(viewModel);

            notify.Should().NotBeNull();
        }
 internal WeakErrorsChangedListener(INotifyDataErrorInfo notifyDataErrorInfo, bool notifyChild, IErrorsChangedListener errorsChangedListener)
 {
     this.notifyDataErrorInfo = notifyDataErrorInfo;
     this.notifyChild = notifyChild;
     notifyDataErrorInfo.ErrorsChanged += new EventHandler<DataErrorsChangedEventArgs>(this.ErrorsChangedCallback);
     this.weakErrorsChangedListener = new WeakReference(errorsChangedListener);
 }
Esempio n. 8
0
        public void ValidateMethodShouldRaiseErrorsChangedEvent()
        {
            int                  countInvoke     = 0;
            ValidatorBase        validator       = GetValidator();
            INotifyDataErrorInfo notifyDataError = validator;

            notifyDataError.ErrorsChanged += (sender, args) =>
            {
                args.PropertyName.ShouldEqual(PropertyToValidate);
                countInvoke++;
            };

            validator.Initialize(new ValidatorContext(new object(), GetServiceProvider()));
            notifyDataError.HasErrors.ShouldBeFalse();
            validator.UpdateErrors(PropertyToValidate, ValidatorErrors, false);
            countInvoke.ShouldEqual(1);
            notifyDataError.HasErrors.ShouldBeTrue();

            if (validator is ManualValidator)
            {
                validator.UpdateErrors(PropertyToValidate, ValidatorErrors, false);
            }
            else
            {
                validator.ValidateAsync(PropertyToValidate);
            }
            countInvoke.ShouldEqual(2);
        }
 public TextViewErrorBinding(TextView target, INotifyDataErrorInfo sourceObject, string sourceProperty)
     : base(target)
 {
     _target = target;
     _sourceObject = sourceObject;
     _sourceProperty = sourceProperty;
     _sourceObject.ErrorsChanged += sourceObject_ErrorsChanged;
 }
Esempio n. 10
0
        /// <summary>
        /// Remove a handler for the given source's event.
        /// </summary>
        public static void RemoveHandler(INotifyDataErrorInfo source, EventHandler<DataErrorsChangedEventArgs> handler)
        {
            if (source == null)
                throw new ArgumentNullException("source");
            if (handler == null)
                throw new ArgumentNullException("handler");

            CurrentManager.ProtectedRemoveHandler(source, handler);
        }
 public ErrorInfoHandler(FrameworkElement element, INotifyDataErrorInfo errorInfo, DependencyProperty dp)
 {
     _element     = element;
     _bindingExpr = element.GetBindingExpression(dp);
     // ReSharper disable once PossibleNullReferenceException
     _propertyName    = _bindingExpr.ResolvedSourcePropertyName;
     _errorInfo       = errorInfo;
     _errorsContainer = errorInfo as IPropertyErrorsContainer;
 }
        /// <summary>
        /// Checks the value core.
        /// </summary>
        /// <param name="validation">The validation.</param>
        /// <exception cref="ValidationException"></exception>
        protected static void CheckValueCore(INotifyDataErrorInfo validation)
        {
            if (validation == null)
                throw new ArgumentNullException(nameof(validation), $"{nameof(validation)} is null.");

            if (validation.HasErrors)
                throw new ValidationException($"Validation errors: "
                    + string.Join(Environment.NewLine + "    ", validation.GetErrors(null).OfType<object>().Select(e => e.ToString())));
        }
Esempio n. 13
0
        private static void SetDataErrorInfoBinding(this DependencyObject element, INotifyDataErrorInfo dataErrorInfo)
        {
            Debug.Assert(dataErrorInfo != null);
            var binding = new System.Windows.Data.Binding(".")
            {
                Source = dataErrorInfo, Mode = BindingMode.TwoWay, ValidatesOnNotifyDataErrors = true
            };

            BindingOperations.SetBinding(element, DummyProperty, binding);
        }
 internal void Disconnect()
 {
     if (this.notifyDataErrorInfo == null)
     {
         return;
     }
     this.notifyDataErrorInfo.ErrorsChanged -= new EventHandler<DataErrorsChangedEventArgs>(this.ErrorsChangedCallback);
     this.notifyDataErrorInfo = null;
     this.weakErrorsChangedListener = null;
 }
Esempio n. 15
0
 internal void Disconnect()
 {
     if (this.notifyDataErrorInfo == null)
     {
         return;
     }
     this.notifyDataErrorInfo.ErrorsChanged -= new EventHandler <DataErrorsChangedEventArgs>(this.ErrorsChangedCallback);
     this.notifyDataErrorInfo       = null;
     this.weakErrorsChangedListener = null;
 }
        public void Entity_EndEditValidatesEntity()
        {
            TestEntity invalidEntity = new TestEntity();

            ((IEditableObject)invalidEntity).BeginEdit();
            invalidEntity.ID1 = "1";
            invalidEntity.ID2 = "1";

            string expectedError = "TestEntity is not valid.";

#if SILVERLIGHT
            INotifyDataErrorInfo notifier = (INotifyDataErrorInfo)invalidEntity;

            // Track what errors existed for the property name at the time of each event
            var actualErrors = new List <Tuple <string, IEnumerable <ValidationResult> > >();
            notifier.ErrorsChanged += (s, e) =>
            {
                actualErrors.Add(Tuple.Create(e.PropertyName, notifier.GetErrors(e.PropertyName).Cast <ValidationResult>()));
            };

            ((IEditableObject)invalidEntity).EndEdit();

            Assert.AreEqual <int>(1, actualErrors.Count, "There should have been a single ErrorsChanged event");

            Tuple <string, IEnumerable <ValidationResult> > error = actualErrors[0];
            Assert.AreEqual <string>(null, error.Item1, "The error should have been an entity-level error (null PropertyName)");

            Assert.AreEqual <int>(1, error.Item2.Count(), "There should have been a single error at the time of the event");
            Assert.AreEqual <string>(expectedError, error.Item2.First().ErrorMessage, "The error message of the single error didn't match the expectation");

            // Clear out the errors for the next stage of the test
            actualErrors.Clear();
#else
            ExceptionHelper.ExpectException <ValidationException>(delegate
            {
                ((IEditableObject)invalidEntity).EndEdit();
            }, expectedError);

            ((IEditableObject)invalidEntity).CancelEdit();
            Assert.IsNull(invalidEntity.ID1);
            Assert.IsNull(invalidEntity.ID2);
#endif

            TestEntity validEntity = new TestEntity();
            ((IEditableObject)validEntity).BeginEdit();
            validEntity.ID1 = "1";
            validEntity.ID2 = "2";
            ((IEditableObject)validEntity).EndEdit();
            Assert.AreEqual("1", validEntity.ID1);
            Assert.AreEqual("2", validEntity.ID2);

#if SILVERLIGHT
            Assert.AreEqual <int>(0, actualErrors.Count, "There should not have been any errors during the valid EndEdit()");
#endif
        }
Esempio n. 17
0
        protected override void OnDetaching()
        {
            base.OnDetaching();
            INotifyDataErrorInfo validation = FindValidation(Target);

            if (validation != null)
            {
                validation.ErrorsChanged -= OnValidationErrorsChanges;
            }
            Target.MouseLeftButtonUp -= OnConfirm;
        }
Esempio n. 18
0
        public static void NotifiesNoDataError(string propertyName, INotifyDataErrorInfo target, Action action)
        {
            var listener = Substitute.For <EventHandler <DataErrorsChangedEventArgs> >();

            target.ErrorsChanged += listener;
            action.Invoke();
            target.ErrorsChanged -= listener;
            listener.Received()
            .Invoke(Arg.Is(target), Arg.Is <DataErrorsChangedEventArgs>(args => args.PropertyName == propertyName));
            Empty(target.GetErrors(propertyName));
        }
Esempio n. 19
0
        protected override void OnAttached()
        {
            base.OnAttached();
            INotifyDataErrorInfo validation = FindValidation(Target);

            if (validation != null)
            {
                Target.IsEnabled          = !validation.HasErrors;
                validation.ErrorsChanged += OnValidationErrorsChanges;
            }
            Target.PreviewMouseLeftButtonUp += OnConfirm;
        }
Esempio n. 20
0
        private static void OnDataContextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            INotifyDataErrorInfo context = e.OldValue as INotifyDataErrorInfo;

            if (context != null)
            {
                RemoveHandler(d, context);
                SetIsValidationAttached(d, false);
            }

            OnValidationPropertyChanged(d, e);
        }
Esempio n. 21
0
        /// <summary>
        /// Remove a handler for the given source's event.
        /// </summary>
        public static void RemoveHandler(INotifyDataErrorInfo source, EventHandler <DataErrorsChangedEventArgs> handler)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }
            if (handler == null)
            {
                throw new ArgumentNullException("handler");
            }

            CurrentManager.ProtectedRemoveHandler(source, handler);
        }
Esempio n. 22
0
        private void Control_DataContextChanged(DependencyObject sender, DataContextChangedEventArgs args)
        {
            if (args.NewValue is INotifyDataErrorInfo notifyDataErrorInfo)
            {
                if (_viewModel != null)
                {
                    _viewModel.ErrorsChanged -= NotifyDataErrorInfo_ErrorsChanged;
                }

                _viewModel = notifyDataErrorInfo;
                notifyDataErrorInfo.ErrorsChanged += NotifyDataErrorInfo_ErrorsChanged;
            }
        }
Esempio n. 23
0
            private void RegisterValidationChangedEvent()
            {
                object SourceItem = this.BindingExpression.PrivateMembers().GetProperty <object>("SourceItem");

                this.notifyDataErrorSourceItem = SourceItem as INotifyDataErrorInfo;
                this.dataErrorSourceItem       = SourceItem as IDataErrorInfo;
                this.sourcePropertyName        = this.BindingExpression.PrivateMembers().GetProperty <string>("SourcePropertyName");

                if (this.notifyDataErrorSourceItem != null)
                {
                    this.notifyDataErrorSourceItem.ErrorsChanged += this.ErrorsChanged;
                }
            }
        /// <summary>
        /// Checks the value core.
        /// </summary>
        /// <param name="validation">The validation.</param>
        /// <exception cref="ValidationException"></exception>
        protected static void CheckValueCore(INotifyDataErrorInfo validation)
        {
            if (validation == null)
            {
                throw new ArgumentNullException(nameof(validation), $"{nameof(validation)} is null.");
            }

            if (validation.HasErrors)
            {
                throw new ValidationException($"Validation errors: "
                                              + string.Join(Environment.NewLine + "    ", validation.GetErrors(null).OfType <object>().Select(e => e.ToString())));
            }
        }
        /// <summary>
        /// Method will subscibe and unsubsribe Error changed event
        /// Get bindable property path of text property
        /// </summary>
        public void CheckValidation()
        {
            // Reset variables values
            ErrorMessage = "";
            HasError     = false;
            BindingPath  = "";

            if (_NotifyErrors != null)
            {
                // Unsubscribe event
                _NotifyErrors.ErrorsChanged += _NotifyErrors_ErrorsChanged;
                _NotifyErrors = null; // Set null value on binding context change
            }

            // Remove notify scroll to property
            if (_NotifyScroll != null)
            {
                _NotifyScroll.ScrollToProperty -= NotifyScroll_ScrollToProperty;
                _NotifyScroll = null;
            }

            // Do nothing if show error message property value is false
            if (!this.ShowErrorMessage || this.View is null)
            {
                return;
            }

            if (this.View.BindingContext != null && this.View.BindingContext is INotifyDataErrorInfo)
            {
                // Get
                _NotifyErrors = this.View.BindingContext as INotifyDataErrorInfo;

                if (_NotifyErrors == null)
                {
                    return;
                }

                // Subscribe event
                _NotifyErrors.ErrorsChanged += _NotifyErrors_ErrorsChanged;

                // Remove notify scroll to property
                if (this.View.BindingContext is INotifyScrollToProperty)
                {
                    _NotifyScroll = this.View.BindingContext as INotifyScrollToProperty;
                    _NotifyScroll.ScrollToProperty += NotifyScroll_ScrollToProperty;
                }

                this.BindingPath = this.View.GetBindingPath(BindableProperty);
                SetPlaceHolder();
            }
        }
Esempio n. 26
0
 /// <summary>
 /// 指定したViewModelオブジェクトの持つエラー情報をすべてコンソールに出力します。
 /// </summary>
 /// <param name="viewModel">コンソールに出力するViewModelオブジェクト</param>
 private void ConsoleWriteErrorMessages(INotifyDataErrorInfo viewModel)
 {
     if ((viewModel != null) && viewModel.HasErrors)
     {
         var properties = viewModel.GetType().GetProperties();
         foreach (var property in properties)
         {
             foreach (var error in viewModel.GetErrors(property.Name))
             {
                 Output.WriteLine($"{viewModel.GetType().Name}.{property.Name} - {error}");
             }
         }
     }
 }
Esempio n. 27
0
        public void EntityRefValidation()
        {
            City invalidCity       = new City();
            ValidationContext ctxt = new ValidationContext(invalidCity, null, null)
            {
                MemberName = "City"
            };

            Assert.AreNotEqual(Cities.CityPropertyValidator.IsValidCity(invalidCity, ctxt), ValidationResult.Success);

            Zip zip = new Zip()
            {
                Code       = 98053,
                FourDigit  = 8625,
                CityName   = "Redmond",
                CountyName = "King",
                StateName  = "WA"
            };

            INotifyDataErrorInfo notifier = (INotifyDataErrorInfo)zip;

            List <string> actualErrors = new List <string>();

            notifier.ErrorsChanged += (s, e) =>
            {
                actualErrors.Add(e.PropertyName);
            };

            zip.City = invalidCity;

            // With INotifyDataErrorInfo validation, the property will get set, even though it's invalid
            Assert.AreEqual <City>(invalidCity, zip.City, "The value should have been set");
            Assert.IsTrue(actualErrors.SequenceEqual(new string[] { "City", "CityName", "StateName" }), "Expected errors from the City, CityName, and StateName properties on the Zip entity.");

            // Verify that we have the expected validation error for the property
            IEnumerable <ValidationResult> results = zip.ValidationErrors.Where(e => e.MemberNames.Contains("City"));

            Assert.AreEqual <int>(1, results.Count(), "Expected a single error for the property");

            // set to a valid City - expect success
            City validCity = new City
            {
                Name       = "Toledo",
                CountyName = "Lucas",
                StateName  = "OH"
            };

            zip.City = validCity;
        }
Esempio n. 28
0
        private IEnumerable <Validation> GetErrors(INotifyDataErrorInfo viewModel)
        {
            var enumerable = viewModel.GetErrors(null);

            foreach (var item in enumerable)
            {
                if (item is Validation validation)
                {
                    yield return(validation);
                }
                else
                {
                    yield return(Validation.Error(item.ToString()));
                }
            }
        }
        private static string AddHandler(DependencyObject d, INotifyDataErrorInfo context, ContentControl placeholder)
        {
            string property = GetProperty(d);

            EventHandler <DataErrorsChangedEventArgs> contextOnErrorsChanged = (sender, args) =>
            {
                if (args.PropertyName == property)
                {
                    UpdateValidationContent(property, context, placeholder);
                }
            };

            SetEventHandler(d, contextOnErrorsChanged);
            context.ErrorsChanged += contextOnErrorsChanged;
            return(property);
        }
        public void TestExplicitGetErrors()
        {
            var vm = new TestViewModel();

            vm.AddValidationRule <int>(nameof(vm.AProperty), x => new ValidationRuleResult(true, "error"));

            INotifyDataErrorInfo indei = vm;

            object[] indeiErrors = indei
                                   .GetErrors(nameof(vm.AProperty))
                                   .Cast <object>()
                                   .ToArray();

            string[] errors = vm.GetErrors(nameof(vm.AProperty)).ToArray();

            CollectionAssert.AreEqual(errors, indeiErrors);
        }
Esempio n. 31
0
 internal void OnDataErrorsChanged(INotifyDataErrorInfo indei, string propName)
 {
     // if notification was on the right thread, just do the work (normal case)
     if (Dispatcher.Thread == Thread.CurrentThread)
     {
         ParentBindingExpression.UpdateNotifyDataErrors(indei, propName, DependencyProperty.UnsetValue);
     }
     else if (!ParentBindingExpression.IsDataErrorsChangedPending)
     {
         // otherwise invoke an operation to do the work on the right context
         ParentBindingExpression.IsDataErrorsChangedPending = true;
         Engine.Marshal(
             (arg) => { object[] args = (object[])arg;
                        ParentBindingExpression.UpdateNotifyDataErrors((INotifyDataErrorInfo)args[0], (string)args[1], DependencyProperty.UnsetValue);
                        return(null); },
             new object[] { indei, propName });
     }
 }
Esempio n. 32
0
        private static void OnValidationPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            // Check if validation is already attached to the property
            bool isValidationAttached = GetIsValidationAttached(d);

            if (isValidationAttached)
            {
                return;
            }

            string               property    = GetProperty(d);
            ContentControl       placeholder = GetValidationPlaceholder(d);
            INotifyDataErrorInfo context     = GetDataContext(d) as INotifyDataErrorInfo;

            if (!string.IsNullOrEmpty(property) && placeholder != null && context != null)
            {
                SetIsValidationAttached(d, true);
            }
        }
Esempio n. 33
0
        public void NotifyDataErrorInfoShouldGetErrorsFromValidators()
        {
            ValidatableViewModel viewModel       = GetValidatableViewModel();
            INotifyDataErrorInfo notifyDataError = viewModel;

            var validator = viewModel.AddValidator <SpyValidator>(new object());

            notifyDataError.HasErrors.ShouldBeFalse();
            validator.SetErrors(PropToValidate1, PropToValidate1, PropToValidate2);
            notifyDataError.HasErrors.ShouldBeTrue();

            string[] errors = notifyDataError.GetErrors(PropToValidate1).OfType <string>().ToArray();
            errors.Length.ShouldEqual(2);
            errors.Contains(PropToValidate1).ShouldBeTrue();
            errors.Contains(PropToValidate2).ShouldBeTrue();

            validator.SetErrors(PropToValidate1);
            notifyDataError.GetErrors(PropToValidate1).ShouldBeEmpty();
            notifyDataError.HasErrors.ShouldBeFalse();
        }
Esempio n. 34
0
        private void UpdateErrors(INotifyDataErrorInfo viewModel)
        {
            ClearErrors();

            var validations = GetErrors(viewModel).ToList();

            foreach (var validation in validations.Where(x => x.Severity == Validation.IssueSeverity.Error))
            {
                Errors.Add(validation);
            }

            foreach (var validation in validations.Where(x => x.Severity == Validation.IssueSeverity.Warning))
            {
                Warnings.Add(validation);
            }

            HasIssues   = validations.Any();
            HasWarnings = Warnings.Any();
            HasErrors   = Errors.Any();
        }
        private static void CollectErrors(INotifyDataErrorInfo notifyDataErrorInfo, string path, ref List <object> errors)
        {
            var values = notifyDataErrorInfo.GetErrors(path ?? string.Empty);

            if (values == null)
            {
                return;
            }
            foreach (var error in values)
            {
                if (error == null)
                {
                    continue;
                }
                if (errors == null)
                {
                    errors = new List <object>();
                }
                errors.Add(error);
            }
        }
Esempio n. 36
0
		void AttachToNotifyError (INotifyDataErrorInfo element)
		{
			if (CurrentNotifyError == element || !Binding.ValidatesOnNotifyDataErrors)
				return;

			string property = "";
			if (PropertyPathWalker.FinalNode.PropertyInfo != null)
				property = PropertyPathWalker.FinalNode.PropertyInfo.Name;
			if (CurrentNotifyError != null) {
				CurrentNotifyError.ErrorsChanged -= NotifyErrorsChanged;
				MaybeEmitError (null, null);
			}

			CurrentNotifyError = element;

			if (CurrentNotifyError != null) {
				CurrentNotifyError.ErrorsChanged += NotifyErrorsChanged;
				if (CurrentNotifyError.HasErrors) {
					foreach (var v in CurrentNotifyError.GetErrors (property)) {
						MaybeEmitError (v as string, v as Exception);
					}
				} else {
					MaybeEmitError (null, null);
				}
			}
		}
        // fetch errors for the given property
        internal static List<object> GetDataErrors(INotifyDataErrorInfo indei, string propertyName)
        {
            const int RetryCount = 3;
            List<object> result = null;
            if (indei != null && indei.HasErrors)
            {
                // if a worker thread is updating the source's errors while we're trying to
                // read them, the enumerator will throw.   The interface doesn't provide
                // any way to work around this, so we'll just try it a few times hoping
                // for success.
                for (int i=RetryCount; i>=0; --i)
                {
                    try
                    {
                        result = new List<object>();
                        IEnumerable ie = indei.GetErrors(propertyName);
                        if (ie != null)
                        {
                            foreach (object o in ie)
                            {
                                result.Add(o);
                            }
                        }
                        break;
                    }
                    catch (InvalidOperationException)
                    {
                        // on the last try, let the exception bubble up
                        if (i == 0)
                            throw;
                    }
                }
            }

            if (result != null && result.Count == 0)
                result = null;

            return result;
        }
        // fetch the current data errors from the source object (and its value),
        // and update the list of data-error ValidationResults accordingly
        internal void UpdateNotifyDataErrors(INotifyDataErrorInfo indei, string propertyName, object value)
        {
            if (!ValidatesOnNotifyDataErrors || IsDetached)
                return;

            // replace the value object, if it has changed
            WeakReference dataErrorWR = (WeakReference)GetValue(Feature.DataErrorValue, null);
            INotifyDataErrorInfo dataErrorValue = (dataErrorWR == null) ? null : dataErrorWR.Target as INotifyDataErrorInfo;
            if (value != DependencyProperty.UnsetValue && value != dataErrorValue && IsDynamic)
            {
                if (dataErrorValue != null)
                    ErrorsChangedEventManager.RemoveHandler(dataErrorValue, OnErrorsChanged);

                INotifyDataErrorInfo newDataErrorValue = value as INotifyDataErrorInfo;
                object newDataErrorWR = ReplaceReference(dataErrorWR, newDataErrorValue);
                SetValue(Feature.DataErrorValue, newDataErrorWR, null);
                dataErrorValue = newDataErrorValue;

                if (newDataErrorValue != null)
                    ErrorsChangedEventManager.AddHandler(newDataErrorValue, OnErrorsChanged);
            }

            // fetch the errors from the last item and from its value
            IsDataErrorsChangedPending = false;
            try
            {
                List<object> propertyErrors = GetDataErrors(indei, propertyName);
                List<object> valueErrors = GetDataErrors(dataErrorValue, String.Empty);
                List<object> errors = MergeErrors(propertyErrors, valueErrors);

                UpdateNotifyDataErrorValidationErrors(errors);
            }
            catch (Exception ex)
            {   // if GetErrors or the enumerators throw, leave the old errors in place
                if (CriticalExceptions.IsCriticalApplicationException(ex))
                    throw;
            }
        }
Esempio n. 39
0
 private void GetNotifyDataErrorInfoInstances(out string propertyName, out INotifyDataErrorInfo notifyDataErrorInfo, out INotifyDataErrorInfo notifyChildDataErrorInfo)
 {
     propertyName = null;
     notifyDataErrorInfo = null;
     notifyChildDataErrorInfo = null;
     if (this.listener != null && this.listener.FullPathExists)
     {
         notifyDataErrorInfo = this.listener.LeafItem as INotifyDataErrorInfo;
         if (notifyDataErrorInfo != null)
         {
             propertyName = this.listener.LeafPropertyName;
         }
         if (this.listener.LeafProperty != null)
         {
             notifyChildDataErrorInfo = this.listener.LeafValue as INotifyDataErrorInfo;
         }
     }
 }
 /// <summary>
 /// Checks an INDEI data object for errors on the specified path. New errors are added to the
 /// list of validation results.
 /// </summary>
 /// <param name="indei">INDEI object to validate.</param>
 /// <param name="bindingProperty">Name of the property to validate.</param>
 /// <param name="bindingPath">Path of the binding.</param>
 /// <param name="declaringPath">Path of the INDEI object.</param>
 /// <param name="validationResults">List of results to add to.</param>
 /// <param name="wireEvents">True if the ErrorsChanged event should be subscribed to.</param>
 private void ValidateIndei(INotifyDataErrorInfo indei, string bindingProperty, string bindingPath, string declaringPath, List<ValidationResult> validationResults, bool wireEvents)
 {
     if (indei != null)
     {
         if (indei.HasErrors)
         {
             IEnumerable errors = null;
             ValidationUtil.CatchNonCriticalExceptions(() => { errors = indei.GetErrors(bindingProperty); });
             if (errors != null)
             {
                 foreach (object errorItem in errors)
                 {
                     if (errorItem != null)
                     {
                         string errorString = null;
                         ValidationUtil.CatchNonCriticalExceptions(() => { errorString = errorItem.ToString(); });
                         if (!string.IsNullOrEmpty(errorString))
                         {
                             ValidationResult validationResult;
                             if (!string.IsNullOrEmpty(bindingProperty))
                             {
                                 validationResult = new ValidationResult(errorString, new List<string>() { bindingPath });
                                 this._propertyValidationResults.Add(validationResult);
                             }
                             else
                             {
                                 Debug.Assert(string.IsNullOrEmpty(bindingPath));
                                 validationResult = new ValidationResult(errorString);
                             }
                             validationResults.AddIfNew(validationResult);
                             this._indeiValidationResults.AddIfNew(validationResult);
                         }
                     }
                 }
             }
         }
         if (wireEvents)
         {
             indei.ErrorsChanged += new EventHandler<DataErrorsChangedEventArgs>(ValidationItem_ErrorsChanged);
             if (!this._validationItems.ContainsKey(indei))
             {
                 this._validationItems.Add(indei, declaringPath);
             }
         }
     }
 }
Esempio n. 41
0
 internal void OnDataErrorsChanged(INotifyDataErrorInfo indei, string propName)
 {
     // if notification was on the right thread, just do the work (normal case)
     if (Dispatcher.Thread == Thread.CurrentThread)
     {
         ParentBindingExpression.UpdateNotifyDataErrors(indei, propName, DependencyProperty.UnsetValue);
     }
     else if (!ParentBindingExpression.IsDataErrorsChangedPending)
     {
         // otherwise invoke an operation to do the work on the right context
         ParentBindingExpression.IsDataErrorsChangedPending = true;
         Engine.Marshal(
             (arg) => {  object[] args = (object[])arg;
                         ParentBindingExpression.UpdateNotifyDataErrors((INotifyDataErrorInfo)args[0], (string)args[1], DependencyProperty.UnsetValue);
                         return null; },
             new object[]{indei, propName});
     }
 }
Esempio n. 42
0
 private void UpdateNotifyDataErrorInfos()
 {
     INotifyDataErrorInfo notifyDataErrorInfo;
     INotifyDataErrorInfo notifyDataErrorInfo1;
     INotifyDataErrorInfo notifyDataErrorInfo2;
     INotifyDataErrorInfo notifyDataErrorInfo3;
     if (this.binding.ValidatesOnNotifyDataErrors)
     {
         string str = null;
         this.GetNotifyDataErrorInfoInstances(out str, out notifyDataErrorInfo, out notifyDataErrorInfo1);
         bool flag = notifyDataErrorInfo != this.currentNotifyDataErrorInfo;
         bool flag1 = notifyDataErrorInfo1 != this.currentNotifyChildDataErrorInfo;
         if (flag || flag1)
         {
             this.ResetNotifyDataErrorInfo(flag, flag1);
             this.currentNotifyDataErrorInfo = notifyDataErrorInfo;
             this.currentNotifyChildDataErrorInfo = notifyDataErrorInfo1;
             string str1 = str;
             if (flag)
             {
                 notifyDataErrorInfo2 = this.currentNotifyDataErrorInfo;
             }
             else
             {
                 notifyDataErrorInfo2 = null;
             }
             if (flag1)
             {
                 notifyDataErrorInfo3 = this.currentNotifyChildDataErrorInfo;
             }
             else
             {
                 notifyDataErrorInfo3 = null;
             }
             this.ConsumeNotifyDataErrorInfo(str1, notifyDataErrorInfo2, notifyDataErrorInfo3);
         }
     }
 }
Esempio n. 43
0
 private void NotifyNewDataErrorInfos(string propertyName, INotifyDataErrorInfo notifyDataErrorInfo, bool isNotifyChildDataErrorInfo)
 {
     IEnumerable errors = null;
     try
     {
         errors = notifyDataErrorInfo.GetErrors(propertyName);
     }
     catch (Exception e)
     {
         Debug.WriteLine(e.ToString());
         if (e is OutOfMemoryException || e is StackOverflowException || e is AccessViolationException || e is ThreadAbortException)
         {
             throw;
         }
     }
     this.NotifyNewDataErrorInfos(this.RegisterErrorCollection(propertyName, errors, isNotifyChildDataErrorInfo));
 }
Esempio n. 44
0
 private void ResetNotifyDataErrorInfo(bool resetCurrentNotifyDataErrorInfo, bool resetCurrentNotifyChildDataErrorInfo)
 {
     if (resetCurrentNotifyDataErrorInfo & this.currentNotifyDataErrorInfo != null)
     {
         if (this.errorsChangedListener != null)
         {
             this.errorsChangedListener.Disconnect();
             this.errorsChangedListener = null;
         }
         this.currentNotifyDataErrorInfo = null;
     }
     if (resetCurrentNotifyChildDataErrorInfo && this.currentNotifyChildDataErrorInfo != null)
     {
         if (this.childErrorsChangedListener != null)
         {
             this.childErrorsChangedListener.Disconnect();
             this.childErrorsChangedListener = null;
         }
         this.currentNotifyChildDataErrorInfo = null;
     }
     if (resetCurrentNotifyDataErrorInfo)
     {
         this.NotifyOldDataErrorInfos(false);
     }
     if (resetCurrentNotifyChildDataErrorInfo)
     {
         this.NotifyOldDataErrorInfos(true);
     }
 }
Esempio n. 45
0
 private void ConsumeNotifyDataErrorInfo(string propertyName, INotifyDataErrorInfo notifyDataErrorInfo, INotifyDataErrorInfo notifyChildDataErrorInfo)
 {
     if (notifyDataErrorInfo != null && this.binding.Mode != BindingMode.OneTime)
     {
         this.errorsChangedListener = new WeakErrorsChangedListener(notifyDataErrorInfo, false, this);
     }
     if (notifyChildDataErrorInfo != null && this.binding.Mode != BindingMode.OneTime)
     {
         this.childErrorsChangedListener = new WeakErrorsChangedListener(notifyChildDataErrorInfo, true, this);
     }
     if (notifyDataErrorInfo != null)
     {
         this.NotifyNewDataErrorInfos(propertyName, notifyDataErrorInfo, false);
     }
     if (notifyChildDataErrorInfo != null)
     {
         this.NotifyNewDataErrorInfos(string.Empty, notifyChildDataErrorInfo, true);
     }
 }
Esempio n. 46
0
 /// <summary>
 /// 指定したViewModelオブジェクトの持つエラー情報をすべてコンソールに出力します。
 /// </summary>
 /// <param name="viewModel">コンソールに出力するViewModelオブジェクト</param>
 private void ConsoleWriteErrorMessages(INotifyDataErrorInfo viewModel)
 {
     if ((viewModel != null) && viewModel.HasErrors)
     {
         var properties = viewModel.GetType().GetProperties();
         foreach (var property in properties)
         {
             foreach (var error in viewModel.GetErrors(property.Name))
             {
                 Output.WriteLine($"{viewModel.GetType().Name}.{property.Name} - {error}");
             }
         }
     }
 }
 private static void CollectErrors(INotifyDataErrorInfo notifyDataErrorInfo, string path, ref List<object> errors)
 {
     var values = notifyDataErrorInfo.GetErrors(path ?? string.Empty);
     if (values == null)
         return;
     foreach (var error in values)
     {
         if (error == null)
             continue;
         if (errors == null)
             errors = new List<object>();
         errors.Add(error);
     }
 }