Reliure DynamicObject à un DataGrid avec la génération automatique des colonnes?
-
20-09-2019 - |
Question
Je suis encore à expérimenter avec DynamicObjects. Maintenant, je besoin de quelques informations: Je suis en train de lier un objet héritant de DynamicObject à un DataGrid WPF (pas de Silverlight).
Comment puis-je obtenir le DataGrid pour créer automatiquement ses colonnes à partir des propriétés publiques disponibles de l'objet qui sont généralement générés à l'exécution? Est-ce possible en fait?
La solution
Il n'y a pas de façon uniforme pour interroger les propriétés dynamiques, généralement il est prévu que vous les connaissez à l'avance. Avec DynamicObject
, peut passer outre GetMemberNames
implémenteurs et que vous donne généralement les propriétés, mais il est vraiment destiné pour le débogage, car il n'y a pas besoin de lui fournir toutes les propriétés. Sinon, si c'est votre propre DynamicObject
vous suffit d'écrire votre propre méthode pour obtenir les propriétés en fonction de votre mise en œuvre dynamique. Par exemple ExpandoObject
vous permet d'interroger toutes les propriétés à l'aide de l'interface IDictionary
.
Donc, une fois que vous avez un moyen d'obtenir vos propriétés que vous devez dire au DataGrid. Malheureusement, avec une grille de données, la question avec la mise en œuvre ICustomTypeDescriptor
de dire la DataGrid sur vos propriétés est que DataGrid obtient les TypeDescriptors en utilisant le type de ne pas l'instance, ce qui est un problème pour les objets dynamiques, mais la mise en œuvre ITypedList
sur la collecte de DynamicObjects travaillera avec le très petite Gotcha de si vous ne mettez pas en œuvre l'interface IList
non-générique sur votre collection, il sera dépouillé avant qu'il arrive au point où il vérifie ITypeList
.
Donc en résumé, Mettre en oeuvre une collection avec ITypedList
et IList
. Avec null ITypedList
de retour pour GetListName
et juste mettre en œuvre GetItemProperties(PropertyDescriptor[] listAccessors)
; Ignorer listAccessors
et retourner un PropertyDescriptorCollection de propertyDescriptors pour chaque membre nommé sur la base la mieux représentée instance d'objet dynamique dans la liste (le plus probable que le premier objet). Vous ne devez mettre en œuvre une sous-classe de PropertyDescriptor, un moyen facile et général à la valeur / setter est d'utiliser le cadre de opensource 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);
}
}
}
Autres conseils
Je pense que le DataGrid
utilise TypeDescriptor
pour obtenir les propriétés de l'objet pour créer les colonnes. Donc, vous devriez être en mesure d'atteindre cet objectif si votre DynamicObject
implémente ICustomTypeDescriptor
. Mettre en œuvre la méthode de GetProperties
afin qu'il retourne les propriétés dynamiques de votre objet.