Wpf 通过自动列生成将DynamicObject绑定到DataGrid?
我仍在尝试动态对象。现在我需要一些信息:我正在尝试将从DynamicObject继承的对象绑定到WPF数据网格(不是Silverlight)Wpf 通过自动列生成将DynamicObject绑定到DataGrid?,wpf,data-binding,datagrid,c#-4.0,dynamicobject,Wpf,Data Binding,Datagrid,C# 4.0,Dynamicobject,我仍在尝试动态对象。现在我需要一些信息:我正在尝试将从DynamicObject继承的对象绑定到WPF数据网格(不是Silverlight) 如何让DataGrid从通常在运行时生成的对象的可用公共属性自动创建其列?实际上可能吗?我认为DataGrid使用TypeDescriptor获取对象属性来创建列。因此,如果您的DynamicObject实现了ICustomTypeDescriptor,您应该能够实现这一点。实现GetProperties方法,以便它返回对象的动态属性。查询动态属性没有统一
如何让DataGrid从通常在运行时生成的对象的可用公共属性自动创建其列?实际上可能吗?我认为
DataGrid
使用TypeDescriptor
获取对象属性来创建列。因此,如果您的DynamicObject
实现了ICustomTypeDescriptor
,您应该能够实现这一点。实现GetProperties
方法,以便它返回对象的动态属性。查询动态属性没有统一的方法,通常希望您提前知道它们。使用DynamicObject
,实现者可以重写GetMemberNames
,这通常会为您提供属性,但是它实际上是用于调试的,因为不要求它提供所有属性。否则,如果它是您自己的DynamicObject
,您只需编写自己的方法即可根据动态实现获取属性。例如,ExpandoObject
允许您使用IDictionary
界面查询所有属性
因此,一旦您有了获取属性的方法,就需要告诉DataGrid。不幸的是,对于DataGrid,实现ICustomTypeDescriptor
来告诉DataGrid您的属性的问题是DataGrid使用类型而不是实例来获取TypeDescriptor,这对于动态对象来说是个问题,但是,在DynamicObjects集合上实现ITypedList
会带来非常小的麻烦,如果不在集合上实现非通用的IList
接口,它将在检查ITypeList
之前被剥离
总之,使用ITypedList
和IList
实现一个集合。使用ITypedList
为GetListName
返回null,只需实现GetItemProperties(PropertyDescriptor[]listAccessors)
;忽略listAccessors
,并根据列表中表示最好的动态对象实例(很可能只是第一个对象)为每个命名成员返回PropertyDescriptor的PropertyDescriptor集合。您确实需要实现PropertyDescriptor的子类,获取/设置值的一种简单而通用的方法是使用开源框架
这是Silverlight在任何情况下都可以使用的方法,因为SL没有
ITypedList
。这也适用于winforms。非常感谢你!
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);
}
}
}