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; namespace CtrEditor { 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); // 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, 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; } } }