Wpf 通过自动列生成将DynamicObject绑定到DataGrid?

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方法,以便它返回对象的动态属性。查询动态属性没有统一

我仍在尝试动态对象。现在我需要一些信息:我正在尝试将从DynamicObject继承的对象绑定到WPF数据网格(不是Silverlight)


如何让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);
            }
        }
}