Rob*_*ert 4 c# datagridview winforms
我有一个网格,我正在设置DataSource一个List<IListItem>.我想要的是让列表绑定到底层类型,并显示这些属性,而不是在中定义的属性IListItem.所以:
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; };
}
Run Code Online (Sandbox Code Playgroud)
如何绑定到网格,以便如果我List<IListItem>包含用户,我将看到特定于用户的字段?编辑:请注意,我想绑定到Datagrid的任何给定列表将由单个底层类型组成.
数据绑定到列表遵循以下策略:
IListSource?如果是这样,转到2的结果GetList()IList?如果没有,抛出错误; 清单预计ITypedList?如果是这样,请将其用于元数据(退出)public Foo this[int index](对某些人来说Foo)?如果是这样,typeof(Foo)用于元数据list[0])作为元数据List<IListItem>落在上面的"4",因为它有一个类型的类型索引器IListItem- 因此它将通过获取元数据TypeDescriptor.GetProperties(typeof(IListItem)).
所以现在,您有三种选择:
TypeDescriptionProvider返回属性的IListItem- 我不确定这是否可行,因为你不可能知道具体的类型是什么IListItemList<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
}
}
});
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3859 次 |
| 最近记录: |