我仍在尝试使用 DynamicObjects。现在我需要一些信息:我正在尝试将从 DynamicObject 继承的对象绑定到 WPF DataGrid(不是 Silverlight)。
如何让 DataGrid 从通常在运行时生成的对象的可用公共属性中自动创建其列?这实际上可能吗?
我仍在尝试使用 DynamicObjects。现在我需要一些信息:我正在尝试将从 DynamicObject 继承的对象绑定到 WPF DataGrid(不是 Silverlight)。
如何让 DataGrid 从通常在运行时生成的对象的可用公共属性中自动创建其列?这实际上可能吗?
查询动态属性没有统一的方法,通常希望您提前知道它们。使用DynamicObject
,实现者可能会覆盖GetMemberNames
并且通常会为您提供属性,但是它实际上是为了调试,因为它不要求它提供所有属性。否则,如果它是您自己的DynamicObject
,您只需编写自己的方法即可根据您的动态实现获取属性。例如ExpandoObject
,您可以使用该IDictionary
界面查询所有属性。
所以一旦你有办法获得你的属性,你需要告诉 DataGrid。不幸的是,对于 DataGrid,实现ICustomTypeDescriptor
告诉 DataGrid 您的属性的问题是 DataGrid 使用 Type 而不是实例获取 TypeDescriptors,这对于动态对象来说是一个问题,但是ITypedList
在 DynamicObjects 集合上实现将适用于非常小的如果你没有IList
在你的集合上实现非通用接口,它会在到达它检查ITypeList
.
所以总而言之,用ITypedList
and实现一个集合IList
。使用ITypedList
return null forGetListName
并执行 GetItemProperties(PropertyDescriptor[] listAccessors)
; 忽略listAccessors
并返回 PropertyDescriptor 的 PropertyDescriptorCollection,每个成员根据列表中表现最好的 Dynamic 对象实例(很可能只是第一个对象)命名。您必须实现 PropertyDescriptor 的子类,获取/设置值的一种简单而通用的方法是使用开源框架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);
}
}
}
我认为获取对象属性以创建列的DataGrid
用途。TypeDescriptor
所以你应该能够实现这一点,如果你的DynamicObject
工具ICustomTypeDescriptor
。实现该GetProperties
方法,使其返回对象的动态属性。