128 lines
4.7 KiB
C#
128 lines
4.7 KiB
C#
using CtrEditor.ObjetosSim;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Dynamic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
|
|
namespace CtrEditor.Serialization
|
|
{
|
|
/// <summary>
|
|
/// Clase para gestionar qué propiedades deben ser locales en objetos globales
|
|
/// </summary>
|
|
public static class PropiedadesLocalesManager
|
|
{
|
|
// Definición de propiedades por defecto que se guardan localmente para todos los objetos
|
|
private static readonly List<string> PropiedadesPorDefecto = new List<string>
|
|
{
|
|
"Left", "Top", "Ancho", "Alto"
|
|
};
|
|
|
|
// Diccionario que contiene conjuntos de propiedades locales por tipo de objeto
|
|
private static readonly Dictionary<Type, List<string>> PropiedadesPorTipo = new Dictionary<Type, List<string>>();
|
|
|
|
/// <summary>
|
|
/// Registra un conjunto de propiedades locales para un tipo específico de objeto
|
|
/// </summary>
|
|
/// <typeparam name="T">Tipo de objeto (debe heredar de osBase)</typeparam>
|
|
/// <param name="propiedades">Lista de nombres de propiedades a registrar como locales</param>
|
|
public static void RegistrarPropiedadesParaTipo<T>(List<string> propiedades) where T : osBase
|
|
{
|
|
PropiedadesPorTipo[typeof(T)] = propiedades;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Obtiene la lista de propiedades que deben ser locales para un objeto concreto
|
|
/// </summary>
|
|
/// <param name="objeto">Objeto del que obtener las propiedades locales</param>
|
|
/// <returns>Lista de nombres de propiedades</returns>
|
|
public static List<string> ObtenerPropiedadesLocales(osBase objeto)
|
|
{
|
|
var resultado = new List<string>(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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Crea un objeto dinámico que permite acceder a las propiedades locales de un objeto
|
|
/// </summary>
|
|
/// <param name="objeto">Objeto del que crear una vista dinámica</param>
|
|
/// <returns>Objeto dinámico con propiedades locales</returns>
|
|
public static dynamic CrearAccesoDinamico(osBase objeto)
|
|
{
|
|
return new PropiedadesLocalesDinamicas(objeto);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clase interna que implementa un acceso dinámico a propiedades
|
|
/// </summary>
|
|
private class PropiedadesLocalesDinamicas : DynamicObject
|
|
{
|
|
private readonly osBase _objeto;
|
|
private readonly List<string> _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<string> GetDynamicMemberNames()
|
|
{
|
|
return _propiedadesLocales;
|
|
}
|
|
}
|
|
}
|
|
} |