在CurrencyManager中获取数据源的属性

时间:2014-09-26 05:24:09

标签: c# winforms reflection data-binding

在设计期间,我的控件应该公开数据源中可用的所有字段。例如,考虑以下数据源结构

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)中添加数据,此代码将失败。

请分享您的想法和想法

1 个答案:

答案 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;
        }

注意:

我只发布代码以显示数据源中的所有可用字段。将字段绑定到控件的代码是不同的。因为,它与我未在此发布的问题无关。