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; }
/// <summary> /// Method will fire on property changed /// Check validation of text property /// Set validation if any validation message on property changed event /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void _NotifyErrors_ErrorsChanged(object sender, DataErrorsChangedEventArgs e) { // Error changed if (e.PropertyName.Equals(this.BindingPath)) { // Get errors string errors = _NotifyErrors .GetErrors(e.PropertyName) ?.Cast <string>() .FirstOrDefault(); // If has error // assign validation values if (!string.IsNullOrEmpty(errors)) { // HasError = true; //set has error value to true // ErrorMessage = errors; // assign error this.InvokeSetPrivatePropertyAction(true, errors); } else { // reset error message and flag // HasError = false; // ErrorMessage = ""; this.InvokeSetPrivatePropertyAction(false, ""); } } }
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; } }
/// <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()))); }
private void HandlerAllErrorsChanged(object sender, DataErrorsChangedEventArgs e) { var name = e.PropertyName; if (name == _propertyName) { UpdateValidationError(_errorInfo.GetErrors(name).Cast <string>()); } }
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 }
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)); }
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(); }
public void NotifyDataErrorInfoTest() { ValidatorBase validator = GetValidator(); INotifyDataErrorInfo notifyDataError = validator; validator.Initialize(new ValidatorContext(new object(), GetServiceProvider())); notifyDataError.HasErrors.ShouldBeFalse(); validator.UpdateErrors(PropertyToValidate, ValidatorErrors, false); notifyDataError.HasErrors.ShouldBeTrue(); string[] errors = notifyDataError .GetErrors(PropertyToValidate) .OfType <string>() .ToArray(); errors.Length.ShouldEqual(1); errors.Contains(ValidatorError).ShouldBeTrue(); validator.UpdateErrors(PropertyToValidate, null, false); notifyDataError.GetErrors(PropertyToValidate).ShouldBeEmpty(); notifyDataError.HasErrors.ShouldBeFalse(); }
/// <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 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())); } } }
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); }
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); } }
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); } } }
/// <summary> /// Converts a value. /// </summary> /// <param name="value">The value produced by the binding source.</param> /// <param name="targetType">The type of the binding target property.</param> /// <param name="parameter">The converter parameter to use.</param> /// <param name="culture">The culture to use in the converter.</param> /// <returns> /// A converted value. If the method returns <c>null</c>, the valid <c>null</c> value is used. /// </returns> public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { switch (targetType) { case object when targetType == typeof(bool): return(instance.HasErrors); case object when targetType == typeof(Visibility): IEnumerable <ValidationResult> errors = (IEnumerable <ValidationResult>)instance.GetErrors(columnName); if (errors.Any()) { return(Visibility.Visible); } else { return(Visibility.Collapsed); } default: // Null-forgiving because null is a valid return value. return(instance.GetErrors(columnName).Cast <object>().FirstOrDefault() !); } }
/// <summary> /// Method will fire on property changed /// Check validation of text property /// Set validation if any validation message on property changed event /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void _NotifyErrors_ErrorsChanged(object sender, DataErrorsChangedEventArgs e) { // Error changed if (e.PropertyName.Equals(this.BindingPath)) { // Get errors string errors = _NotifyErrors .GetErrors(e.PropertyName) ?.Cast <string>() .FirstOrDefault(); if (!string.IsNullOrEmpty(errors)) { HasError = true; //set has error value to true ErrorMessage = errors; // assign error } else { // reset error message and flag HasError = false; ErrorMessage = ""; } } }
// 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; }
/// <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()))); } }
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)); }
private static void ShouldHaveError(INotifyDataErrorInfo notify, string property, string expectedError) { notify.HasErrors.Should().BeTrue(); string.Join(", ", notify.GetErrors(property).OfType <string>().ToArray()) .Should().Be(expectedError); }
/// <summary> /// 指定したプロパティがエラーかどうかを判定します。 /// </summary> /// <param name="self">自分自身</param> /// <param name="propertyName">判定対象のプロパティ名</param> /// <returns>判定結果(true:エラーです。, false:正常です。)</returns> public static bool HasPropertyError(this INotifyDataErrorInfo self, string propertyName) { return(self.GetErrors(propertyName).OfType <string>().Any()); }
/// <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); } } } }
public static bool HasErrorMessagesFor(this INotifyDataErrorInfo notifyDataErrorInfo, string propertyName) => notifyDataErrorInfo.GetErrors(propertyName)?.OfType <string>() is IEnumerable <string> list && list.Any();
public static IEnumerable <string> GetErrorMessagesFor(this INotifyDataErrorInfo notifyDataErrorInfo, string propertyName) => notifyDataErrorInfo.GetErrors(propertyName)?.OfType <string>().ToList();
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); } } }
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); } }
public IEnumerable GetErrors(string propertyName) { return(validationTemplate.GetErrors(propertyName)); }