C#的DataSource格多态性 [英] C# grid DataSource polymorphism

查看:86
本文介绍了C#的DataSource格多态性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个网格,我设置了数据源列表< IListItem> 。我想是有列表绑定到底层类型,DISPLY这些属性,而不是在 IListItem 定义的属性。所以:

I have a grid, and I'm setting the DataSource to a List<IListItem>. What I want is to have the list bind to the underlying type, and disply those properties, rather than the properties defined in 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; };
}



我如何绑定到一个网格,这样,如果我的列表< IListItem> 包含用户,我会看到用户特定的领域?编辑:请注意,任何给定的名单我想绑定到DataGrid将包括一个单一的基础类型的

How do I bind to a grid so that if my List<IListItem> contains users I will see the user-specific field? Note that any given list I want to bind to the Datagrid will be comprised of a single underlying type.

推荐答案

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

Data-binding to lists follows the following strategy:


  1. 没有数据源实施 IListSource ?如果是这样,转到2的结果的GetList()

  2. 没有数据源实施的IList ?如果没有,抛出一个错误;预计名单

  3. 没有数据源实施 ITypedList ?如果是使用元数据(出口)

  4. 做数据源有一个非对象索引,公共美孚此[INT指数] (对于某些)?如果是这样,使用 typeof运算(富)的元数据

  5. 有列表中的什么吗?如果是这样,请使用第一项(列表[0] )元数据

  6. 没有可用的元数据

  1. does the data-source implement IListSource? if so, goto 2 with the result of GetList()
  2. does the data-source implement IList? if not, throw an error; list expected
  3. does the data-source implement ITypedList? if so use this for metadata (exit)
  4. does the data-source have a non-object indexer, public Foo this[int index] (for some Foo)? if so, use typeof(Foo) for metadata
  5. is there anything in the list? if so, use the first item (list[0]) for metadata
  6. no metadata available

列表< IListItem> 落入4以上的,因为它有一个类型的类型化索引 IListItem - 因此它会得到通过 TypeDescriptor.GetProperties(typeof运算(IListItem))

List<IListItem> falls into "4" above, since it has a typed indexer of type IListItem - and so it will get the metadata via TypeDescriptor.GetProperties(typeof(IListItem)).

所以,现在,你有三种选择:

So now, you have three options:


  • TypeDescriptionProvider 返回的属性, IListItem - 我不知道这是可行的,因为你不可能知道具体类型给出刚 IListItem

  • 使用正确类型的列表(列表<使用者> 等) - 仅仅作为一个得到的简单方法的的IList 与非对象索引

  • ITypedList 包装(很多工作)

  • 使用类似的ArrayList (即没有公开非对象索引) - 非常哈克

  • write a TypeDescriptionProvider that returns the properties for IListItem - I'm not sure this is feasible since you can't possibly know what the concrete type is given just IListItem
  • use the correctly typed list (List<User> etc) - simply as a simple way of getting an IList with a non-object indexer
  • write an ITypedList wrapper (lots of work)
  • use something like ArrayList (i.e. no public non-object indexer) - very hacky!

我的选择是使用正确类型列表<> ..这里是一个自动施放方法,这是否对你的,而不必知道类型(样本使用);

My preference is for using the correct type of List<>... here's an AutoCast method that does this for you without having to know the types (with sample usage);

请注意,这仅适用于同质数据(即所有对象都一样),它需要在列表中的至少一个对象来推断类型...

Note that this only works for homogeneous data (i.e. all the objects are the same), and it requires at least one object in the list to infer the type...

// 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#的DataSource格多态性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆