C# 网格数据源多态

2023-12-01

我有一个网格,我正在设置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>包含用户我会看到用户特定字段吗?编辑:请注意,我想要绑定到数据网格的任何给定列表都将由单个基础类型组成。


到列表的数据绑定遵循以下策略:

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

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(使用前将#替换为@)

C# 网格数据源多态 的相关文章

随机推荐