在设计期间,我的控件应该公开数据源中可用的所有字段。例如,考虑以下数据源结构
List<Data> dataSource = new List<Data>()
dataSource.add(new Data(){ Value = 1, Rect = new Rectangle(10, 10, 10, 10)})
我想将控件与数据源中的内部属性绑定,如Rectangle的"Left"
属性。我使用以下代码来实现此目的
var prop = this.BindingContext[dataSource];
ArrayList result = (ArrayList)GetPropertiesList(prop.Current, string.Empty);
GetPropertiesList方法的代码如下
private IList GetPropertiesList(object source, string parent)
{
ArrayList result = new ArrayList();
ArrayList innerProperties = new ArrayList();
Type sourceType = source.GetType();
PropertyInfo[] propertyInfo = sourceType.GetProperties();
if (parent != string.Empty)
parent += ".";
foreach (PropertyInfo info in propertyInfo)
{
object value = info.GetValue(source, null);
if(value == null)
result.Add(parent + info.Name);
else if (value is string || value is DateTime || value.GetType().IsPrimitive)
result.Add(parent + info.Name);
else
innerProperties = (ArrayList)(GetPropertiesList(value, parent + info.Name));
}
if(innerProperties.Count > 0)
result.AddRange(innerProperties);
return result;
}
如果未在列表对象(dataSource
)中添加数据,此代码将失败。
请分享您的想法和想法
答案 0 :(得分:0)
我不想回答我的问题,但我认为这可能有助于其他人。
经过几个小时的搜索,我发现使用属性描述符我们可以得到一个属性名称,类型,值,子属性等等,所以我只是稍微修改了我的代码。
解决方案中的代码将填充数据源中所有可用的基元,字符串和日期时间属性(包括数据源内对象的基元,字符串和日期时间属性)。所以使用它我可以在我的设计师中显示内部属性。
我的问题中的数据源将在设计器中显示如下:
Value
Rect.Left
Rect.Top
Rect.Width
Rect.Height
......
<强>解决方案:强>
PropertyDescriptorCollection members = dataSourceObject.GetItemProperties();
result = (ArrayList)GetPropertiesList(members, string.Empty);
结果将包含数组列表中的所有属性。循环遍历数组列表,我可以得到各个属性的名称
函数GetPropertiesList的代码:
private IList GetPropertiesList(PropertyDescriptorCollection collection, string parent)
{
ArrayList result = new ArrayList();
if (parent != string.Empty)
parent += '.';
foreach (PropertyDescriptor property in collection)
{
if (property.PropertyType == typeof(string) || property.PropertyType == typeof(DateTime) || property.PropertyType.IsPrimitive)
result.Add(parent + property.Name);
else
{
result.AddRange((ArrayList)GetPropertiesList(property.GetChildProperties(), parent+ property.Name));
}
}
return result;
}
注意:强>
我只发布代码以显示数据源中的所有可用字段。将字段绑定到控件的代码是不同的。因为,它与我未在此发布的问题无关。