好的,这是一个艰难的。
简介:我的想法是将我编写的instanciated QueryBuilder类附加到PropertyGrid。 QueryBuilder类现在包含几个字段,这些字段是硬编码的,如下例所示。因此允许用户指定应以何种方式在查询中使用哪些字段(排序,分组等)。在用户为这些属性指定了所有设置后(通过代码或通过PropertyGrid GUI),QueryBuilder能够生成查询。一切都很好。伪代码:
class QueryBuilder {
public QBField name {get; set;}
public QBField prename {get; set;}
public QBField zip {get; set;}
// ...
public void QueryBuilder() {
name = new QBField();
prename = new QBField();
// ...
}
public getQuery() {
// logic to build the query
}
}
class QBField {
public bool shown {get; set;}
public bool sortby {get; set;}
public bool groupby {get; set;}
}
挑战:现在我不想将每个字段硬编码为QueryBuilder类中的公共属性,而是想知道如何使用包含所有字段的List<string>
来“填充”我的实例化具有这些属性的QueryBuilder。
所以这导致了三个问题:
这可以通过以某种方式覆盖QueryBuilder类的Type的GetProperties()来实现,如果是,那么它最好如何完成?
如何在运行时生成的QBField属性中迭代所有这些并生成它们?想法:PropertyDescriptors和Activators?
如何迭代所有这些属性来读取每个QBField对象的值?我遇到的问题是,当用反射读取QBField的属性并尝试getValue(obj,null)时,当然需要的第一个参数是一个对象,我不知道,因为我有很多这些QBField对象。也许把我所有的QBField都放到List<QBField>
并迭代它?这会在这个例子中起作用吗?
我只是有点迷失,但我觉得我非常接近解决方案。因此,对于正确方向的任何帮助或指示都非常感激!
答案 0 :(得分:5)
PropertyGrid
可以通过TypeConverter
,ICustomTypeDescriptor
和/或TypeDescriptionProvider
受到影响。其中,TypeConverter
是最简单的,通过覆盖GetProperties
(并将其标记为支持)。
在任何情况下,您还需要编写一个PropertyDescriptor
实现,该实现知道如何获取字段和对象,并获取/设置值,即
public override void SetValue(object component, object value) {
((YourType)component)[fieldNameSetInConstructor] = value;
}
这是一个基本的属性包,它将所有内容公开为string
;显然,当您扩展它(不同的属性类型,更改通知等)时,它会变得更加复杂。另请注意,此TypeConverter
方法仅适用于PropertyGrid
;对于DataGridView
等,您需要ICustomTypeDescriptor
或TypeDescriptionProvider
。对于收藏,您需要ITypedList
。对于特定场景,边缘周围还有大约20个其他接口。但是你得到了重点; p关键是我们的PropertyDescriptor
充当你的实际模型(在我的情况下是字典)和你公开的模型{{1 (每个键的假属性)。
TypeDescriptor