public ValidationMessageInfo GetFirstMessage(IEnumerable <ValidationMessageInfo> messageInfos) { //find first error ValidationMessageInfo find = messageInfos.FirstOrDefault(x => x.Type == ValidationMessageType.Error); if (find != null) { return(find); } //find first warning find = messageInfos.FirstOrDefault(x => x.Type == ValidationMessageType.Warning); if (find != null) { return(find); } return(messageInfos.FirstOrDefault()); }
public static void OnPropertyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs de) { if (BaseViewModel.IsDesignTime) { return; } var name = de.NewValue.ToString(); //var elementProperty = d.GetType().GetProperty(name); var descriptor = DependencyPropertyDescriptor.FromName(name, d.GetType(), d.GetType()); var action = new EventHandler((s, e) => { var element = (FrameworkElement)s; var propertyChanged = element.DataContext as IValidationPropertyChanged; if (propertyChanged == null) { return; } // throw new Exception($"your model have to inheritance IValidationPropertyChanged [model type]: [{s.GetType()}] [binding type]: [{de.Property.PropertyType}]"); else if (propertyChanged.AllMessages == null) { throw new Exception($"your model AllMessages propety cannot be null [model type]: [{s.GetType()}] [binding type]: [{de.Property.PropertyType}]"); } else if (propertyChanged.MessagesByProperty == null) { throw new Exception($"your model MessagesByProperty propety cannot be null [model type]: [{s.GetType()}] [binding type]: [{de.Property.PropertyType}]"); } if (descriptor == null && element is PasswordBox password) { if (password.DataContext is BaseViewModel bvm) { bvm.OnPropertyChanged(name); } return; } var binding = System.Windows.Data.BindingOperations.GetBindingExpression(((FrameworkElement)d), descriptor.DependencyProperty); if (binding == null) { return; } var property = d.GetType().GetProperty(name); var objectValue = property.GetValue(d, null); if (descriptor.DependencyProperty.PropertyType == typeof(string) && objectValue != null && string.IsNullOrEmpty(objectValue.ToString()) && Nullable.GetUnderlyingType(property.PropertyType) != null) { property.SetValue(d, null, null); } if (binding != null) { binding.UpdateSource(); } var bindingPropertyName = ""; bool hasError = false; var mainValue = property.GetValue(d, null); //propertyChanged.AllMessages.Clear(); //foreach (var item in propertyChanged.MessagesByProperty) //{ // item.Value.Items.Clear(); //} // var objectInstance = GetContext(binding, out bindingPropertyName); if (objectInstance == null) { return; } var typeOfData = objectInstance.GetType(); property = typeOfData.GetProperty(bindingPropertyName); if (property == null) { throw new Exception($"property {bindingPropertyName} not found on {objectInstance}"); } string fullNameOfProperty = typeOfData.FullName + "." + property.Name; if (property != null) { if (ValidationsHelperExtensions.PropertyValidations.ContainsKey(propertyChanged) && ValidationsHelperExtensions.PropertyValidations[propertyChanged].Any(x => x.ModelInstances.ContainsKey(objectInstance) || x.ModelTypes.ContainsKey(typeOfData))) { var properties = ValidationsHelperExtensions.PropertyValidations[propertyChanged].Where(x => x.ModelInstances.ContainsKey(objectInstance) || x.ModelTypes.ContainsKey(typeOfData)); //var properties = ValidationsHelperExtensions.PropertyValidations[propertyChanged][typeOfData]; foreach (var propertyValidation in properties) { if (!propertyValidation.RealTimeCheck && !(e is IsValidationBuilderEventArgs)) { continue; } propertyValidation.HasError = false; foreach (var instance in propertyValidation.ModelInstances) { CheckInstance(instance.Key); } CheckInstance(objectInstance); void CheckInstance(object instance) { if (propertyValidation.ModelInstances.Values.Count > 0) { bool myHasError = false; if (propertyValidation.LockHasError && propertyValidation.LockHasErrorWasTrue) { myHasError = true; } foreach (var validateProp in propertyValidation.ModelInstances.Where(x => x.Key == instance).SelectMany(x => x.Value)) { var myFullNameOfProperty = typeOfData.FullName + "." + validateProp.Name; if (propertyChanged.MessagesByProperty.ContainsKey(myFullNameOfProperty)) { foreach (var item in propertyChanged.MessagesByProperty[myFullNameOfProperty].Items.Where(x => x.Instance == instance).ToList()) { propertyChanged.MessagesByProperty[myFullNameOfProperty].Items.Remove(item); } } else { propertyChanged.MessagesByProperty[myFullNameOfProperty] = new ViewModelItemsInfo() { Items = new ObservableCollection <ValidationMessageInfo>(), ViewModel = new ValidationMessageViewModel() { CurrentViewModel = propertyChanged, PropertyName = myFullNameOfProperty } } }; foreach (var attrib in validateProp.Validations) { ValidationMessageInfo error = null; attrib.GetMessage(mainValue); if (validateProp.Name == property.Name && instance == objectInstance) { error = attrib.GetMessage(mainValue); } else { var myproperty = instance.GetType().GetProperty(validateProp.Name); var value = myproperty.GetValue(instance); error = attrib.GetMessage(value); } if (error != null) { error.Instance = instance; error.PropertyName = validateProp.Name; myHasError = true; if (validateProp.Name == property.Name) { propertyChanged.AllMessages.Remove(propertyChanged.AllMessages.FirstOrDefault(x => x.PropertyName == validateProp.Name && x.Instance == instance)); propertyChanged.AllMessages.Add(error); } propertyChanged.MessagesByProperty[myFullNameOfProperty].Items.Remove( propertyChanged.MessagesByProperty[myFullNameOfProperty].Items.FirstOrDefault(x => x.PropertyName == validateProp.Name && x.Instance == instance)); propertyChanged.MessagesByProperty[myFullNameOfProperty].Items.Add(error); propertyChanged.MessagesByProperty[myFullNameOfProperty].ViewModel?.Validate(); break; } else { propertyChanged.AllMessages.Remove(propertyChanged.AllMessages.FirstOrDefault(x => x.PropertyName == validateProp.Name && x.Instance == instance)); } } } propertyValidation.HasError = propertyValidation.HasError || myHasError; if (myHasError) { hasError = true; propertyValidation.LockHasErrorWasTrue = true; } } } } } else { if (!propertyChanged.MessagesByProperty.ContainsKey(fullNameOfProperty)) { propertyChanged.MessagesByProperty[fullNameOfProperty] = new ViewModelItemsInfo { Items = new ObservableCollection <ValidationMessageInfo>() }; } var attributes = property.GetCustomAttributes(typeof(ValidationAttribute), true); if (attributes.Length > 0) { if (propertyChanged.MessagesByProperty.ContainsKey(fullNameOfProperty)) { propertyChanged.MessagesByProperty[fullNameOfProperty].Items.Clear(); } foreach (ValidationAttribute attrib in attributes) { //var valueOfProperty = property.GetValue(objectInstance, null); var error = attrib.GetMessage(mainValue); if (error != null) { error.Instance = objectInstance; error.PropertyName = bindingPropertyName; hasError = true; propertyChanged.AllMessages.Remove(propertyChanged.AllMessages.FirstOrDefault(x => x.PropertyName == bindingPropertyName && x.Instance == objectInstance)); propertyChanged.AllMessages.Add(error); propertyChanged.MessagesByProperty[fullNameOfProperty].Items.Remove( propertyChanged.MessagesByProperty[fullNameOfProperty].Items.FirstOrDefault(x => x.PropertyName == bindingPropertyName && x.Instance == objectInstance)); propertyChanged.MessagesByProperty[fullNameOfProperty].Items.Add(error); break; } } propertyChanged.MessagesByProperty[fullNameOfProperty].ViewModel?.Validate(); } else { return; } } } if (!hasError) { propertyChanged.AllMessages.Remove(propertyChanged.AllMessages.FirstOrDefault(x => x.PropertyName == bindingPropertyName)); } if (propertyChanged.MessagesByProperty.ContainsKey(fullNameOfProperty)) { var myErrors = propertyChanged.MessagesByProperty[fullNameOfProperty]; binding.ParentBinding.ValidationRules.Clear(); foreach (var item in myErrors.Items.Where(x => x.Instance == objectInstance)) { binding.ParentBinding.ValidationRules.Add(new CustomValidationRule(item)); } } binding.UpdateSource(); propertyChanged.HasError = propertyChanged.AllMessages.Count(x => x.Type == ValidationMessageType.Error) > 0; propertyChanged.OnPropertyChanged(nameof(propertyChanged.FirstMessage)); }); ((FrameworkElement)d).Loaded += (s, e) => { action(d, null); }; ValidationMessageViewModel.AllPropertyChanges.Add(() => { action(d, null); }); if (descriptor == null && d is PasswordBox passwordBox) { passwordBox.PasswordChanged += (s, e) => { action(s, null); }; } else { descriptor.AddValueChanged(d, action); ValidationsBuilder.Changed += (validationsBuilder) => { action(d, new IsValidationBuilderEventArgs()); }; } //if (d is FrameworkElement el) // el.Unloaded += (sender, args) => // { // descriptor.RemoveValueChanged(sender, action); // }; }
public CustomValidationRule(ValidationMessageInfo validationMessageInfo) { ValidationMessageInfo = validationMessageInfo; }