将DynamicObject绑定到具有自动列生成的DataGrid? [英] Binding DynamicObject to a DataGrid with automatic column generation?
问题描述
我还在试验DynamicObjects。现在我需要一些信息:我试图将从DynamicObject继承的对象绑定到WPF DataGrid(而不是Silverlight)。
I'm still experimenting with DynamicObjects. Now I need some information: I'm trying to bind an object inheriting from DynamicObject to a WPF DataGrid (not Silverlight).
如何让DataGrid从通常在运行时生成的对象的可用公共属性自动创建列?实际上是可能的吗?
How do I get the DataGrid to automatically create its columns from the available public properties of the object that are typically generated at runtime? Is that possible actually?
推荐答案
没有统一的方式查询动态属性,一般来说,预计你会提前了解它们。使用 DynamicObject
,实现者可以覆盖 GetMemberNames
,这通常为您提供属性,但是它真的用于调试,因为不要求它提供所有属性。否则,如果它是您自己的 DynamicObject
,则只需编写自己的方法即可根据动态实现获取属性。例如 ExpandoObject
可以使用 IDictionary
界面查询所有属性。
There is no uniform way to query dynamic properties, generally it's expected that you know them ahead of time. With DynamicObject
, implementers may override GetMemberNames
and that generally gives you the properties, however it is really meant for debugging because there is no requirement that it provide all properties. Otherwise if it's your own DynamicObject
you just have to write your own method to get the properties based on your dynamic implementation. For example ExpandoObject
lets you query all the properties using the IDictionary
interface.
所以一旦你有办法获取你的属性,你需要告诉DataGrid。不幸的是,使用DataGrid,实现 ICustomTypeDescriptor
告诉DataGrid您的属性的问题是DataGrid使用Type不是实例的TypeDescriptors,这是Dynamic对象的问题但是,如果您不实现非通用的 IList $,那么在DynamicObjects集合上实现
ITypedList
将非常小巧。 c $ c>接口,它将被剥离出来之前检查 ITypeList
。
So once you have a way to get your properties you need to tell the DataGrid. Unfortunately with a DataGrid, the issue with implementing ICustomTypeDescriptor
to tell the DataGrid about your properties is that DataGrid gets the TypeDescriptors using the Type not the instance, which is a problem for Dynamic objects, however implementing ITypedList
on the collection of DynamicObjects will work with the very tiny gotcha of if you don't implement the non-generic IList
interface on your collection, it will be stripped out before it gets to the point where it checks for ITypeList
.
总而言之,使用 ITypedList
和 IList
实现集合。使用 ITypedList
返回null为 GetListName
,只需实现 GetItemProperties(PropertyDescriptor [] listAccessors) code>;忽略
listAccessors
,并返回PropertyDescriptors的PropertyDescriptorCollection,其中每个成员根据列表中最佳表示的Dynamic对象实例(最可能仅仅是第一个对象)命名。你必须实现PropertyDescriptor的一个子类,一个简单而通用的Get / Set值的方法是使用opensource框架 Dynamitey
So in summary, Implement a Collection with ITypedList
and IList
. With ITypedList
return null for GetListName
and just implement GetItemProperties(PropertyDescriptor[] listAccessors)
; Ignore listAccessors
and return a PropertyDescriptorCollection of PropertyDescriptors for each member named based on the best represented Dynamic object instance in your list (most likely just the first object). You do have to implement a subclass of PropertyDescriptor, an easy and general way to the Get/Set value is to use the opensource framework 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);
}
}
}
这篇关于将DynamicObject绑定到具有自动列生成的DataGrid?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!