using CtrEditor.ObjetosSim; using System; using System.Collections.Generic; using System.Dynamic; using System.Linq; using System.Reflection; namespace CtrEditor.Serialization { /// /// Clase para gestionar qué propiedades deben ser locales en objetos globales /// public static class PropiedadesLocalesManager { // Definición de propiedades por defecto que se guardan localmente para todos los objetos private static readonly List PropiedadesPorDefecto = new List { "Left", "Top", "Ancho", "Alto" }; // Diccionario que contiene conjuntos de propiedades locales por tipo de objeto private static readonly Dictionary> PropiedadesPorTipo = new Dictionary>(); /// /// Registra un conjunto de propiedades locales para un tipo específico de objeto /// /// Tipo de objeto (debe heredar de osBase) /// Lista de nombres de propiedades a registrar como locales public static void RegistrarPropiedadesParaTipo(List propiedades) where T : osBase { PropiedadesPorTipo[typeof(T)] = propiedades; } /// /// Obtiene la lista de propiedades que deben ser locales para un objeto concreto /// /// Objeto del que obtener las propiedades locales /// Lista de nombres de propiedades public static List ObtenerPropiedadesLocales(osBase objeto) { var resultado = new List(PropiedadesPorDefecto); if (objeto != null && PropiedadesPorTipo.TryGetValue(objeto.GetType(), out var propiedadesExtra)) { foreach (var prop in propiedadesExtra) { if (!resultado.Contains(prop)) resultado.Add(prop); } } return resultado; } /// /// Crea un objeto dinámico que permite acceder a las propiedades locales de un objeto /// /// Objeto del que crear una vista dinámica /// Objeto dinámico con propiedades locales public static dynamic CrearAccesoDinamico(osBase objeto) { return new PropiedadesLocalesDinamicas(objeto); } /// /// Clase interna que implementa un acceso dinámico a propiedades /// private class PropiedadesLocalesDinamicas : DynamicObject { private readonly osBase _objeto; private readonly List _propiedadesLocales; public PropiedadesLocalesDinamicas(osBase objeto) { _objeto = objeto; _propiedadesLocales = ObtenerPropiedadesLocales(objeto); } public override bool TryGetMember(GetMemberBinder binder, out object result) { var nombrePropiedad = binder.Name; if (_propiedadesLocales.Contains(nombrePropiedad)) { var propInfo = _objeto.GetType().GetProperty(nombrePropiedad); if (propInfo != null && propInfo.CanRead) { result = propInfo.GetValue(_objeto); return true; } } result = null; return false; } public override bool TrySetMember(SetMemberBinder binder, object value) { var nombrePropiedad = binder.Name; if (_propiedadesLocales.Contains(nombrePropiedad)) { var propInfo = _objeto.GetType().GetProperty(nombrePropiedad); if (propInfo != null && propInfo.CanWrite) { try { var valorConvertido = Convert.ChangeType(value, propInfo.PropertyType); propInfo.SetValue(_objeto, valorConvertido); return true; } catch (Exception) { // Silenciar errores de conversión } } } return false; } public override IEnumerable GetDynamicMemberNames() { return _propiedadesLocales; } } } }