C#的DataSource格多态性 [英] C# grid DataSource polymorphism
问题描述
我有一个网格,我设置了数据源
到列表< 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:
- 没有数据源实施
IListSource
?如果是这样,转到2的结果的GetList()
- 没有数据源实施
的IList
?如果没有,抛出一个错误;预计名单 - 没有数据源实施
ITypedList
?如果是使用元数据(出口) - 做数据源有一个非对象索引,
公共美孚此[INT指数]
(对于某些富
)?如果是这样,使用typeof运算(富)
的元数据 - 有列表中的什么吗?如果是这样,请使用第一项(
列表[0]
)元数据 - 没有可用的元数据
- does the data-source implement
IListSource
? if so, goto 2 with the result ofGetList()
- does the data-source implement
IList
? if not, throw an error; list expected - does the data-source implement
ITypedList
? if so use this for metadata (exit) - does the data-source have a non-object indexer,
public Foo this[int index]
(for someFoo
)? if so, usetypeof(Foo)
for metadata - is there anything in the list? if so, use the first item (
list[0]
) for metadata - 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 forIListItem
- I'm not sure this is feasible since you can't possibly know what the concrete type is given justIListItem
- use the correctly typed list (
List<User>
etc) - simply as a simple way of getting anIList
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屋!