Tengo muchas clases personalizadas que estoy usando y explicaré y publicaré ejemplos de. Después de explicar lo que hacen todos, trataré de describir claramente las condiciones bajo las cuales está ocurriendo mi error.Solución de reflexión dinámica personalizada, complicada, C#
En primer lugar, estoy usando un PropertyGrid para mostrar las propiedades de varios tipos diferentes de objetos. Debido a que el enlace predeterminado de PropertyGrid no era tan descriptivo como yo quería que fuera, creé unas pocas clases personalizadas a las que me referiré como clases "Display". Estas clases de visualización se construyen pasando un objeto y luego creando propiedades que devuelven cadenas y descripciones muy bien formateadas para las propiedades públicas (y en algunos casos métodos) del objeto real que se pasó.
Lo demostraré con un código de ejemplo abreviado:
Aquí es un ejemplo de un objeto que desea mostrar en mi PropertyGrid:
public class Joint
{
public Joint(...)
{...}
//properties
public string Name { get; set;}
public CustomObject CC { get; set;}
public List<CustomObject> Custom List { get; set;}
}
la cadena de propiedad "Nombre" muestra bien en el PropertyGrid Sin embargo el CustomObject y lista DID no mostrar de manera que parecía muy útil r amistoso para mí.
Así que intentaron crear una solución escribiendo esta clase:
public class DisplayJoint
{
private Joint _jnt;
public DisplayJoint(Joint jnt)
{
_jnt = jnt;
}
//properties
public string Name { get { return _jnt.Name; } }
[TypeConverterAttribute(typeof(ExpandableObjectConverter))]
public DisplayCustomObject CC { get { return new DisplayCustomObject(_jnt.CC); } }
[TypeConverterAttribute(typeof(ExpandableObjectConverter))]
public List<CustomObject> CustomList { get; set;}
}
Como se puede ver en el código anterior, he creado DisplayClasses especiales tanto para mi clase conjunta y mi clase CustomObject. En mi proyecto, tengo muchos, muchos tipos diferentes de objetos que requieren el mismo tipo de propiedades de clase de pantalla superpuestas.
arriba, Usted puede ver las líneas que he añadido por encima de las dos últimas propiedades
[TypeConverterAttribute (typeof (ExpandableObjectConverter))]
Esta línea resuelve mi problema de mostrar el CustomObject como quiero a en la propertGrid (casi ... más sobre esto más adelante). Sin embargo, no funciona de la misma manera para mi propiedad Lista personalizada. En la lista personalizada, se expande para mostrar únicamente el recuento y la capacidad (las propiedades reales de la lista) Tiene sentido por qué ocurre esto, pero no era lo que yo quería. Quería ver el objeto contenido real dentro de la lista.
Así que aquí es mi solución complicada, tomado inicialmente de this question:
Tengo dos clases que estoy usando para añadir dinámicamente objetos con destino a la lista PropertyGrid en forma de propiedades. El primero (CustomClass) puede ser downloaded here. Se usa para crear dinámicamente propiedades. La segunda clase (DisplayIEnumerable) que estoy utilizando se deriva de la primera y se puede encontrar here.
La clase DisplayIEnumerable recorre los objetos de la lista y agrega una propiedad a sí misma con la información contenida dentro de cada objeto. Se pasa un DisplayClass para definir exactamente cómo deben representarse esas propiedades de los objetos dentro de la Grilla.
¡Hasta este punto todo funciona muy bien!como lo demuestra esta imagen (imagen no se ha creado usando las clases establecidas, las cadenas tienen un formato diferente en las clases que estoy usando, eliminado el formato de código para ayudarle a concentrarse en el código relevante:
Ahora después de eso Intro largo, la verdadera pregunta. Usando las técnicas anteriores, me gustaría escribir una clase que pueda manejar de forma dinámica los CustomObjects para los que no he escrito clases de visualización únicas. Tengo la intención de dejar este código para aquellos que usan la aplicación para probar puede probar de manera más efectiva sin tener que tener una clase de visualización completa para cada uno de los objetos personalizados de la empresa. (hay cientos) En su lugar, al vincular el propertyGrid con la clase siguiente, espero tener todas las propiedades que son listas y CustomObjects que tienen DisplayClasses correspondientes para vincularlos en su lugar.
Aquí está la clase que ya he probado y tengo un error. Todavía no he intentado implementar la sustitución de las listas con mi clase DisplayIEnumerable sin embargo, quería obtener la funcionalidad básica de trabajo en primer lugar:
using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Reflection;
using System.Collections;
using System.Windows.Forms;
internal class DisplayObject : CustomClass<T>
{
#region Variables
protected T _obj;
#endregion
#region Constructor
public DisplayObject(T obj)
{
if (obj != null)
{
try
{
Type currentType = typeof(T);
foreach (PropertyInfo propertyInfo in currentType.GetProperties())
{
Attribute[] attributes = new Attribute[1];
if (propertyInfo.GetType() is IEnumerable)
attributes[0] = new TypeConverterAttribute(typeof(ExpandableObjectConverter));
else
attributes[0] = null;
this.Add(new CustomProperty(propertyInfo.Name, propertyInfo, propertyInfo.GetType(), false, true, attributes));
}
}
catch
{
MessageBox.Show("Failure!");
}
}
}
#endregion
#region Properties
[Browsable(false)]
public object Item
{
get { return _obj; }
set { _obj = value; }
}
#endregion
}
Cuando se ejecuta, aparece El PropertyGrid como debería:
Sin embargo , una vez que se hace clic en la flecha Expandir, no pasa nada, y la flecha desaparece:
lo que está mal en la clase anterior que no es malo en mi clase DisplayIEnumerable, que causa esta variación en el comportamiento?
Estoy utilizando la clase DisplayObject como este (dentro de un displayclass):
[TypeConverterAttribute(typeof(ExpandableObjectConverter))]
public DisplayObject EndJoint { get { if (_member.bcEnd != null) { return new DisplayObject(_member.EndJoint); } else return null; } }
Gracias de antemano! Estaré muy impresionado si alguien supera esta pregunta.
Por qué ¿no utilizas una colección estándar UITypeEditor (el formulario estándar con dos columnas)? –
Porque no podré agregar recursivamente este atributo expandible a las propiedades que se encuentran dentro de las propiedades. Quiero que el usuario pueda profundizar tanto como lo desee para ver completamente las relaciones entre los diferentes objetos. – jth41
El formulario de recopilación estándar incluye una cuadrícula de propiedades, por lo que también es recurrente. –