我有一个网格,我正在设置DataSource
to a List<IListItem>
。我想要的是将列表绑定到基础类型,并显示这些属性,而不是中定义的属性IListItem
. So:
public interface IListItem
{
string Id;
string Name;
}
public class User : IListItem
{
string Id { get; set; };
string Name { get; set; };
string UserSpecificField { get; set; };
}
public class Location : IListItem
{
string Id { get; set; };
string Name { get; set; };
string LocationSpecificField { get; set; };
}
我如何绑定到网格,以便如果我的List<IListItem>
包含用户我会看到用户特定字段吗?编辑:请注意,我想要绑定到数据网格的任何给定列表都将由单个基础类型组成。
到列表的数据绑定遵循以下策略:
- 数据源是否实现
IListSource
?如果是,则转至 2,结果为GetList()
- 数据源是否实现
IList
?如果没有,则抛出错误;预期列表
- 数据源是否实现
ITypedList
?如果是这样,请使用它作为元数据(退出)
- 数据源是否有非对象索引器,
public Foo this[int index]
(对于一些Foo
)?如果是这样,请使用typeof(Foo)
对于元数据
- 清单上有什么吗?如果是这样,请使用第一项(
list[0]
) 对于元数据
- 没有可用的元数据
List<IListItem>
属于上面的“4”,因为它有一个 type 的类型化索引器IListItem
- 因此它将通过以下方式获取元数据TypeDescriptor.GetProperties(typeof(IListItem))
.
所以现在,你有三个选择:
- write a
TypeDescriptionProvider
返回属性IListItem
- 我不确定这是否可行,因为你不可能知道给出的具体类型是什么IListItem
- 使用正确输入的列表(
List<User>
等)-只是作为获得的简单方法IList
使用非对象索引器
- 写一个
ITypedList
包装器(大量工作)
- 使用类似的东西
ArrayList
(即没有公共非对象索引器) - 非常hacky!
我的偏好是使用正确类型List<>
...这是一个AutoCast
为您执行此操作的方法无需知道类型(带有示例用法);
请注意,这仅适用于同类数据(即所有对象都相同),并且它需要列表中至少有一个对象来推断类型...
// infers the correct list type from the contents
static IList AutoCast(this IList list) {
if (list == null) throw new ArgumentNullException("list");
if (list.Count == 0) throw new InvalidOperationException(
"Cannot AutoCast an empty list");
Type type = list[0].GetType();
IList result = (IList) Activator.CreateInstance(typeof(List<>)
.MakeGenericType(type), list.Count);
foreach (object obj in list) result.Add(obj);
return result;
}
// usage
[STAThread]
static void Main() {
Application.EnableVisualStyles();
List<IListItem> data = new List<IListItem> {
new User { Id = "1", Name = "abc", UserSpecificField = "def"},
new User { Id = "2", Name = "ghi", UserSpecificField = "jkl"},
};
ShowData(data, "Before change - no UserSpecifiedField");
ShowData(data.AutoCast(), "After change - has UserSpecifiedField");
}
static void ShowData(object dataSource, string caption) {
Application.Run(new Form {
Text = caption,
Controls = {
new DataGridView {
Dock = DockStyle.Fill,
DataSource = dataSource,
AllowUserToAddRows = false,
AllowUserToDeleteRows = false
}
}
});
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)