gpt4 book ai didi

C# 网格数据源多态

转载 作者:行者123 更新时间:2023-12-02 03:10:42 25 4
gpt4 key购买 nike

我有一个网格,我正在设置 DataSourceList<IListItem> 。我想要的是将列表绑定(bind)到基础类型,并显示这些属性,而不是 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; };
}

如何绑定(bind)到网格,以便如果我的 List<IListItem>包含用户我会看到用户特定字段吗?编辑:请注意,我想要绑定(bind)到数据网格的任何给定列表都将由单个基础类型组成。

最佳答案

列表数据绑定(bind)遵循以下策略:

  1. 数据源是否实现 IListSource ?如果是,则转到 2,结果为 GetList()
  2. 数据源是否实现 IList ?如果不是,则抛出错误;预期列表
  3. 数据源是否实现 ITypedList ?如果是这样,请使用它作为元数据(退出)
  4. 数据源是否有非对象索引器,public Foo this[int index] (对于某些 Foo )?如果是这样,请使用 typeof(Foo)对于元数据
  5. 列表中有什么内容吗?如果是这样,请使用第一项 ( list[0] ) 作为元数据
  6. 没有可用的元数据

List<IListItem>属于上面的“4”,因为它有一个类型为 IListItem 的类型化索引器- 因此它将通过 TypeDescriptor.GetProperties(typeof(IListItem)) 获取元数据.

现在,您有三个选择:

  • 写一个TypeDescriptionProvider返回 IListItem 的属性- 我不确定这是否可行,因为您不可能知道 IListItem 给出的具体类型是什么
  • 使用正确键入的列表( List<User> 等) - 只是作为获取 IList 的简单方法使用非对象索引器
  • 写一个ITypedList包装器(大量工作)
  • 使用类似 ArrayList 的内容(即没有公共(public)非对象索引器) - 非常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
}
}
});
}

关于C# 网格数据源多态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/927383/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com