2010-03-18 6 views
8

Todavía estoy experimentando con DynamicObjects. Ahora necesito algo de información: estoy intentando vincular un objeto que hereda de DynamicObject a WPF DataGrid (no Silverlight).¿Enlace de DynamicObject a un DataGrid con generación automática de columnas?

¿Cómo obtengo que DataGrid cree automáticamente sus columnas a partir de las propiedades públicas disponibles del objeto que normalmente se generan en tiempo de ejecución? ¿Es eso posible en realidad?

Respuesta

10

No hay una manera uniforme de consultar propiedades dinámicas, generalmente se espera que las conozca con anticipación. Con DynamicObject, los implementadores pueden anular GetMemberNames y eso generalmente le da las propiedades, sin embargo, está realmente destinado a la depuración porque no es necesario que proporcione todas las propiedades. De lo contrario, si es su propio DynamicObject, solo tiene que escribir su propio método para obtener las propiedades en función de su implementación dinámica. Por ejemplo, ExpandoObject le permite consultar todas las propiedades usando la interfaz IDictionary.

Una vez que tenga una forma de obtener sus propiedades, tendrá que decirle al DataGrid. Desafortunadamente con un DataGrid, el problema con la implementación de ICustomTypeDescriptor para decirle a DataGrid sobre sus propiedades es que DataGrid obtiene los TypeDescriptors usando Type, no la instancia, que es un problema para los objetos dinámicos, sin embargo, la implementación de ITypedList en la colección de DynamicObjects funcionará con muy pequeño, si no implementa la interfaz no genérica IList en su colección, será eliminada antes de que llegue al punto donde comprueba ITypeList.

Por lo tanto, en resumen, implementar una colección con ITypedList y IList. Con ITypedList devuelva nulo para GetListName y simplemente implemente GetItemProperties(PropertyDescriptor[] listAccessors); Ignore listAccessors y devuelva un PropertyDescriptorCollection de PropertyDescriptors para cada miembro nombrado en función de la instancia de objeto dinámico mejor representada en su lista (lo más probable es que sea el primer objeto). Usted tiene que poner en práctica una subclase de PropertyDescriptor, una forma fácil y general para el valor/Set obtiene es utilizar el marco de código abierto Dynamitey

using System; 
using System.ComponentModel; 
using Dynamitey; 
public class DynamicPropertyDescriptor:PropertyDescriptor 
{ 
     public DynamicPropertyDescriptor(string name) : base(name, null) 
     { 
     } 

     public override bool CanResetValue(object component) 
     { 
      return false; 
     } 

     public override object GetValue(object component) 
     { 
      return Dynamic.InvokeGet(component, Name); 
     } 

     public override void ResetValue(object component) 
     { 

     } 

     public override void SetValue(object component, object value) 
     { 
      Dynamic.InvokeSet(component, Name, value); 
     } 

     public override bool ShouldSerializeValue(object component) 
     { 
      return false; 
     } 

     public override Type ComponentType 
     { 
      get { return typeof(object); } 
     } 

     public override bool IsReadOnly 
     { 
      get { return false; } 
     } 

     public override Type PropertyType 
     { 
      get 
      { 
       return typeof (object); 
      } 
     } 
} 
+0

esto funciona también en winforms. ¡Muchas gracias! – swe

2

Creo que el DataGrid usa TypeDescriptor para obtener las propiedades del objeto para crear las columnas. Por lo tanto, debería poder lograr esto si su DynamicObject implementa ICustomTypeDescriptor. Implemente el método GetProperties para que devuelva las propiedades dinámicas de su objeto.

+0

Este es el camino a seguir con Silverlight en cualquier caso, como SL doesn' t tiene 'ITypedList'. – McGarnagle

Cuestiones relacionadas