using System.Globalization; using System.Windows.Data; using System.Windows.Media; using System.Windows; using System.ComponentModel; using System.Reflection; using Xceed.Wpf.Toolkit.PropertyGrid.Editors; using Xceed.Wpf.Toolkit; using Xceed.Wpf.Toolkit.PropertyGrid; using CtrEditor.ObjetosSim.Extraccion_Datos; using CtrEditor.ObjetosSim; using System.Collections.ObjectModel; using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; using System.Collections; using CommunityToolkit.Mvvm.ComponentModel; namespace CtrEditor { public partial class ObjetosSimulablesFilterTypes : ObservableObject { [ObservableProperty] public bool cloned; [ObservableProperty] public bool enable_On_All_Pages; [ObservableProperty] public bool show_On_This_Page; } public class ListItemPropertyDescriptor : PropertyDescriptor { private readonly IList owner; private readonly int index; public ListItemPropertyDescriptor(IList owner, int index) : base($"[{index}]", null) { this.owner = owner; this.index = index; } public override AttributeCollection Attributes { get { var attributes = TypeDescriptor.GetAttributes(GetValue(null), false); //If the Xceed expandable object attribute is not applied then apply it if (!attributes.OfType().Any()) { attributes = AddAttribute(new ExpandableObjectAttribute(), attributes); } //set the xceed order attribute attributes = AddAttribute(new PropertyOrderAttribute(index), attributes); return attributes; } } private AttributeCollection AddAttribute(Attribute newAttribute, AttributeCollection oldAttributes) { Attribute[] newAttributes = new Attribute[oldAttributes.Count + 1]; oldAttributes.CopyTo(newAttributes, 1); newAttributes[0] = newAttribute; return new AttributeCollection(newAttributes); } public override bool CanResetValue(object component) { return false; } public override object GetValue(object component) { return Value; } private T Value => owner[index]; public override void ResetValue(object component) { throw new NotImplementedException(); } public override void SetValue(object component, object value) { owner[index] = (T)value; } public override bool ShouldSerializeValue(object component) { return false; } public override Type ComponentType => owner.GetType(); public override bool IsReadOnly => false; public override Type PropertyType => Value?.GetType(); } public class MyExpandableIListConverter : ExpandableObjectConverter { public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) { if (value is IList list) { PropertyDescriptorCollection propDescriptions = new PropertyDescriptorCollection(null); IEnumerator enumerator = list.GetEnumerator(); int counter = -1; while (enumerator.MoveNext()) { counter++; propDescriptions.Add(new ListItemPropertyDescriptor(list, counter)); } return propDescriptions; } else { return base.GetProperties(context, value, attributes); } } } public static class TypeDecorationManager { public static void AddExpandableObjectConverter(Type T) { TypeDescriptor.AddAttributes(T, new TypeConverterAttribute(typeof(ExpandableObjectConverter))); TypeDescriptor.AddAttributes(T, new ExpandableObjectAttribute()); } public static void AddExpandableIListConverter(Type T) { TypeDescriptor.AddAttributes(T, new TypeConverterAttribute(typeof(MyExpandableIListConverter))); TypeDescriptor.AddAttributes(T, new ExpandableObjectAttribute()); } } public class SubclassFilterConverter : IValueConverter { public Type TargetType { get; set; } public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is ObservableCollection collection && TargetType != null) { var filteredCollection = new ObservableCollection(collection.Where(x => x.GetType() == TargetType)); return filteredCollection; } return null; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } public class BoolToVisibilityConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is bool boolValue) { return boolValue ? Visibility.Visible : Visibility.Collapsed; } return Visibility.Collapsed; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { if (value is Visibility visibility) { return visibility == Visibility.Visible; } return false; } } public class DecimalEditor : ITypeEditor { public FrameworkElement ResolveEditor(PropertyItem propertyItem) { var doubleUpDown = new DoubleUpDown { FormatString = "F3", Increment = 0.001, Maximum = 200000.599, MinWidth = 100 }; var binding = new Binding("Value") { Source = propertyItem, Converter = new DecimalConverter(), Mode = BindingMode.TwoWay, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged }; BindingOperations.SetBinding(doubleUpDown, DoubleUpDown.ValueProperty, binding); return doubleUpDown; } } public class DecimalConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is double doubleValue) { return doubleValue.ToString("0.00", culture); // Formatear a dos decimales } if (value is float floatValue) { return floatValue.ToString("0.00", culture); // Formatear a dos decimales } return value; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { if (double.TryParse(value as string, NumberStyles.Any, CultureInfo.InvariantCulture, out double doubleValue)) { return doubleValue; } if (float.TryParse(value as string, NumberStyles.Any, CultureInfo.InvariantCulture, out float floatValue)) { return floatValue; } return value; } } public class ColorToBrushConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is Color color) { return new SolidColorBrush(color); } return Binding.DoNothing; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { if (value is SolidColorBrush brush) { return brush.Color; } return Binding.DoNothing; } } [AttributeUsage(AttributeTargets.Property)] public class HiddenAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property)] public class DisplayNameAttribute : Attribute { public string DisplayName { get; } public DisplayNameAttribute(string displayName) { DisplayName = displayName; } } public class StringToBrushConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is string colorString) { return (Brush)new BrushConverter().ConvertFromString(colorString); } return Brushes.Transparent; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } public class SumConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { if (values.Length == 2 && values[0] is float value1 && values[1] is float value2) { return (double) (value1 + value2); } return DependencyProperty.UnsetValue; } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } public class VerticalPositionConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is double altura && double.TryParse(parameter?.ToString(), out double factor)) { return altura * factor; } return 0; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } public class HalfWidthConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is double width) { return (width / 2.0) - (double.Parse(parameter.ToString()) / 2.0); } return 0; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } public class WidthPercentageConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is double width) { return width * 0.25; } return 0; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } public class LevelToHeightMultiConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { if (values[0] is float level && values[1] is double containerHeight) { return containerHeight * (level / 100); } return 0; } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } public class BrushToColorNameConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (value is SolidColorBrush brush) { if (brush == Brushes.Red) return "Rojo"; if (brush == Brushes.Blue) return "Azul"; if (brush == Brushes.Black) return "Negro"; if (brush == Brushes.Green) return "Verde"; if (brush == Brushes.Gray) return "Gris"; } return "Unknown"; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (value is string colorName) { switch (colorName) { case "Rojo": return Brushes.Red; case "Azul": return Brushes.Blue; case "Negro": return Brushes.Black; case "Verde": return Brushes.Green; case "Gris": return Brushes.Gray; } } return Brushes.Transparent; } } public class PixelToMeter { // Instancia privada estática, parte del patrón Singleton private static PixelToMeter? _instance; public UnitConverter calc = new UnitConverter(0.01f); // Propiedad pública estática para acceder a la instancia public static PixelToMeter Instance { get { if (_instance == null) { _instance = new PixelToMeter(); } return _instance; } } } public class MeterToPixelConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value == null) return 0; // Aseguramos que el valor no sea nulo // Convertimos el valor de entrada en un número flotante float meters = System.Convert.ToSingle(value); float factor = 1; // Valor por defecto del factor // Si el parámetro no es nulo, intentamos convertirlo a float if (parameter != null) { string paramStr = parameter.ToString(); // Normalizamos el parámetro para asegurar que el punto sea el separador decimal paramStr = paramStr.Replace(',', '.'); // Utilizamos CultureInfo.InvariantCulture para evitar problemas con el separador decimal if (float.TryParse(paramStr, NumberStyles.Any, CultureInfo.InvariantCulture, out float parsedFactor)) { factor = parsedFactor; // Asignamos el factor parseado si la conversión es exitosa } } // Calculamos los píxeles llamando a la instancia de PixelToMeter y multiplicamos por el factor return PixelToMeter.Instance.calc.MetersToPixels(meters) * factor; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { if (value == null) return 0; // Aseguramos que el valor no sea nulo // Convertimos el valor de entrada en un número flotante float pixels = System.Convert.ToSingle(value); float factor = 1; // Valor por defecto del factor // Si el parámetro no es nulo, intentamos convertirlo a float if (parameter != null) { string paramStr = parameter.ToString(); // Normalizamos el parámetro para asegurar que el punto sea el separador decimal paramStr = paramStr.Replace(',', '.'); // Utilizamos CultureInfo.InvariantCulture para evitar problemas con el separador decimal if (float.TryParse(paramStr, NumberStyles.Any, CultureInfo.InvariantCulture, out float parsedFactor)) { factor = parsedFactor; // Asignamos el factor parseado si la conversión es exitosa } } return PixelToMeter.Instance.calc.PixelsToMeters(pixels) * factor; } } public class MarginConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { if (values.Length == 4 && values[0] is double left && values[1] is double top && values[2] is double right && values[3] is double bottom) { return new Thickness(PixelToMeter.Instance.calc.MetersToPixels((float)left), PixelToMeter.Instance.calc.MetersToPixels((float)top), PixelToMeter.Instance.calc.MetersToPixels((float)right), PixelToMeter.Instance.calc.MetersToPixels((float)bottom)); } return new Thickness(); } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { throw new NotSupportedException("ConvertBack is not supported."); } } public class DistanceToMarginConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is double distance) { return new Thickness(0, 0, 0, PixelToMeter.Instance.calc.MetersToPixels((float)distance)); // Ajustar Bottom a 'distance' } return new Thickness(); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotSupportedException("ConvertBack is not supported."); } } public class FloatToFormattedStringConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is float floatValue) { var r = floatValue.ToString("0.00", culture).Replace('.', ','); // Formatear a dos decimales return r; } return value; // Devolver el valor original si no es un float } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { if (value is string stringValue && float.TryParse(stringValue.Replace(',', '.'), NumberStyles.Float, culture, out float result)) { return result; } return value; // Devolver el valor original si no se puede convertir } } public class DoubleToFormattedStringConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is double floatValue) { return floatValue.ToString("0.00", culture).Replace('.', ','); // Formatear a dos decimales } return value; // Devolver el valor original si no es un float } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { if (value is string stringValue && double.TryParse(stringValue.Replace(',', '.'), NumberStyles.Float, culture, out double result)) { return result; } return value; // Devolver el valor original si no se puede convertir } } public class UnitConverter { // La escala representa cuántos metros hay en un píxel public float Scale { get; private set; } public UnitConverter(float scale) { if (scale <= 0) throw new ArgumentException("Scale must be greater than zero."); Scale = scale; } // Convierte una distancia en metros a píxeles public float MetersToPixels(float meters) { return meters / Scale; } // Convierte una distancia en píxeles a metros public float PixelsToMeters(float pixels) { return pixels * Scale; } // Configurar o ajustar la escala public void SetScale(float newScale) { if (newScale <= 0) throw new ArgumentException("Scale must be greater than zero."); Scale = newScale; } } }