Существует нет единого способа запроса динамических свойств, обычно ожидается, что вы их заранее знаете. С помощью DynamicObject
исполнители могут переопределить GetMemberNames
, и это обычно дает вам свойства, однако оно действительно предназначено для отладки, потому что нет необходимости предоставлять все свойства. В противном случае, если это ваш собственный DynamicObject
, вам просто нужно написать свой собственный метод, чтобы получить свойства на основе вашей динамической реализации. Например, ExpandoObject
позволяет запрашивать все свойства с помощью интерфейса IDictionary
.
Итак, как только у вас есть способ получить ваши свойства, вам нужно сообщить DataGrid. К сожалению, с помощью DataGrid проблема с внедрением ICustomTypeDescriptor
, чтобы сообщить DataGrid о ваших свойствах, заключается в том, что DataGrid получает TypeDescriptors, используя Type, а не экземпляр, что является проблемой для динамических объектов, однако реализация ITypedList
в коллекции DynamicObjects будет работать с очень мала, если вы не реализуете не общий интерфейс IList
в своей коллекции, он будет удален до того, как он доберется до точки, где он проверяет ITypeList
.
Итак, сделайте сборку с ITypedList
и IList
. С ITypedList
возвращает null для GetListName
и просто реализует GetItemProperties(PropertyDescriptor[] listAccessors)
; Игнорируйте listAccessors
и верните PropertyDescriptorCollection of PropertyDescriptors для каждого члена с именем на основе наилучшего представленного экземпляра динамического объекта в вашем списке (скорее всего, только первый объект). Вы должны реализовать подкласс PropertyDescriptor, простой и общий путь к Get/Set значению заключается в использовании Рамочной 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);
}
}
}
это работает и в winforms. Большое спасибо! – swe