diff --git a/IFCGeoRefCheckerGUI/ValueConverters/InputValidations.cs b/IFCGeoRefCheckerGUI/ValueConverters/InputValidations.cs new file mode 100644 index 0000000..e6786ee --- /dev/null +++ b/IFCGeoRefCheckerGUI/ValueConverters/InputValidations.cs @@ -0,0 +1,172 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Globalization; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Media; + +namespace IFCGeoRefCheckerGUI.ValueConverters +{ + public class LatLonRule : ValidationRule + { + public double Min { get; set; } + public double Max { get; set; } + + public LatLonRule() + { + + } + + public override ValidationResult Validate(object value, CultureInfo cultureInfo) + { + double angle = 0.0; + + try + { + if (((string)value).Length > 0) { angle = Double.Parse((string)value, cultureInfo); } + } + catch (Exception e) + { + return new ValidationResult(false, $"Illegal characters or {e.Message}"); + } + + if ((angle < Min) || (angle > Max)) + { + return new ValidationResult(false, $"Please enter an decimal angle between {Min} and {Max}"); + } + return ValidationResult.ValidResult; + } + } + + public class InputValidator + { + public static bool IsValid(DependencyObject parent) + { + /* + return !Validation.GetHasError(parent) && + LogicalTreeHelper.GetChildren(parent).OfType().All(IsValid); + + + bool valid = true; + + LocalValueEnumerator localValues = parent.GetLocalValueEnumerator(); + while (localValues.MoveNext()) + { + LocalValueEntry entry = localValues.Current; + if (BindingOperations.IsDataBound(parent, entry.Property)) + { + Binding binding = BindingOperations.GetBinding(parent, entry.Property); + foreach (ValidationRule rule in binding.ValidationRules) + { + ValidationResult result = rule.Validate(parent.GetValue(entry.Property), null); + if (result!.IsValid) + { + BindingExpression expression = BindingOperations.GetBindingExpression(parent, entry.Property); + System.Windows.Controls.Validation.MarkInvalid(expression, new ValidationError(rule, expression, result.ErrorContent, null)); + } + } + } + } + + /*for (int i = 0; i != VisualTreeHelper.GetChildrenCount(parent); ++i) + { + DependencyObject child = VisualTreeHelper.GetChild(parent, i); + if (!IsValid(child)) { valid = false; return valid; } + }*/ + bool valid = true; + + LocalValueEnumerator localValues = parent.GetLocalValueEnumerator(); + while(localValues.MoveNext()) + { + LocalValueEntry entry = localValues.Current; + if (BindingOperations.IsDataBound(parent, entry.Property)) + { + Binding binding = BindingOperations.GetBinding(parent, entry.Property); + if (binding.ValidationRules.Count > 0) + { + BindingExpression expression = BindingOperations.GetBindingExpression(parent, entry.Property); + expression.UpdateSource(); + + if (expression.HasError) + { + valid = false; + } + } + } + } + + System.Collections.IEnumerable children = LogicalTreeHelper.GetChildren(parent); + foreach (object obj in children) + { + if (obj is DependencyObject) + { + DependencyObject child = (DependencyObject)obj; + if (!IsValid(child)) + { + return false; + } + } + } + + return valid; + //*/ + } + } + + + public class ValidationHelper: INotifyDataErrorInfo + { + readonly IDictionary> errorList = new Dictionary>(); + + public string this[string propertyName] + { + get + { + if (errorList.ContainsKey(propertyName)) + { + return errorList[propertyName].First(); + } + return String.Empty; + } + } + + public bool HasErrors => errorList.Count > 0; + + public event EventHandler? ErrorsChanged; + + public void ClearError([CallerMemberName] string property = "") + { + if (errorList.Remove(property)) + { + ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(property)); + } + + } + public void AddError(string errorMessage, [CallerMemberName] string property = "") + { + if (!errorList.ContainsKey(property)) + { + errorList.Add(property, new List()); + } + errorList[property].Add(errorMessage); + } + + public IEnumerable GetErrors(string? propertyName) + { + if (errorList.ContainsKey(propertyName!)) + { + return errorList[propertyName!]; + } + return Array.Empty(); + } + + } + +} diff --git a/IFCGeoRefCheckerGUI/ValueConverters/Level20UI.cs b/IFCGeoRefCheckerGUI/ValueConverters/Level20UI.cs new file mode 100644 index 0000000..81860b4 --- /dev/null +++ b/IFCGeoRefCheckerGUI/ValueConverters/Level20UI.cs @@ -0,0 +1,42 @@ +using IFCGeoRefCheckerGUI.ViewModels; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IFCGeoRefCheckerGUI.ValueConverters +{ + public class Level20UI : BaseViewModel + { + public double? Latitude { get; set; } + private double? longitude; + public double? Longitude + { + get => longitude; + set + { + if (longitude != value) + { + ValHelper.ClearError(); + + if (value < -180.0 || value > 180.0) + { + ValHelper.AddError("Longitude must be between -180.0 and 180.0 degrees"); + } + longitude = value; + this.RaisePropertyChanged(nameof(Longitude)); + + } + } + } + public double? Elevation { get; set; } + + public string? GUID { get; set; } + + public ValidationHelper ValHelper { get; } = new ValidationHelper(); + public bool HasErrors => ValHelper.HasErrors; + + } +} diff --git a/IFCGeoRefCheckerGUI/ValueConverters/LevelsConverter.cs b/IFCGeoRefCheckerGUI/ValueConverters/LevelsConverter.cs index c51239b..7824475 100644 --- a/IFCGeoRefCheckerGUI/ValueConverters/LevelsConverter.cs +++ b/IFCGeoRefCheckerGUI/ValueConverters/LevelsConverter.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using Xbim.Ifc4.Interfaces; namespace IFCGeoRefCheckerGUI.ValueConverters { @@ -34,6 +35,18 @@ public static Level10UI convertToLevel10UI(Level10 lvl10) return lvl10UI; } + public static Level20UI convertToLevel20UI(Level20 lvl20) + { + var lvl20UI = new Level20UI(); + + lvl20UI.Latitude = lvl20.Latitude; + lvl20UI.Longitude = lvl20.Longitude; + lvl20UI.Elevation = lvl20.Elevation; + lvl20UI.GUID = lvl20.ReferencedEntity?.GlobalId; + + return lvl20UI; + } + public static Level50UI convertToLevel50UI(Level50 lvl50) { var lvl50UI = new Level50UI(); @@ -54,6 +67,7 @@ public static Level50UI convertToLevel50UI(Level50 lvl50) return lvl50UI; } + }