如果你想建立一个可以支持数据绑定的自定义集合,那你至少要实现IList接口或IListSource(在Winform环境中。如果在Asp.net的环境中你只需要实现IEnumerable接口就可以了)。
IList接口继承于ICollection接口而ICollection接口又继承于IEnumerable接口。所以当你实现IList接口的时候就同时实现了另外的两个接口。
IEnumerable接口:实现此接口的集合类可以被foreach迭代。
ICollection接口:实现此接口的集合类具有支持集合的基本特性。如:可以查看集合中的元素的总数等。
IList接口:实现此接口的集合类支持数据绑定的最小化实现。也就是说可以被将其数据绑定到UI元素上。(支持最小化的数据绑定功能)
好,大致介绍到这里。还是看代码慢慢讲解吧!
为了完整的说明实现。我们需要建立两个项目其中
1.WindowForm项目:用来测试用。
2.MyCollectionLibary : 类库项目。我在此建立了两个类,一个Person类和People类。
其中 Person 类表示放入到People集合类的集合项目。People类是个集合类,实现了IList接口,用于维持和管理多个Person对象。
这个项目的代码如下:
Person类的实现:
1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
5
namespace MyCollectionLibary
6![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
7
public class Person
8![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
9
private string _lastname;
10![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
11
public string Lastname
12![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
13![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return _lastname; }
14![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
set
{ _lastname = value; }
15
}
16
private string firstname;
17![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
18
public string Firstname
19![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
20![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return firstname; }
21![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
set
{ firstname = value; }
22
}
23![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public Person()
{ }
24
public Person(string firstName, string lastName)
25![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
26
this.Lastname = lastName;
27
this.Firstname = firstname;
28
}
29
}
30
}
31![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
1.Person类中只有两个属性(为了保持例子的简单行)。
2.请注意我保留了一个不带任何参数的构造函数,这个构造函数又可能会被数据绑定使用所以请保留下来。(见26行)
People类的实现:
请先using System.Collections命名空间。
public class People : IList ,然后“显示实现接口”(不一定必须要这样做)。
1
using System;
2
using System.Collections;
3
using System.Collections.Generic;
4
using System.Text;
5![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
6
namespace MyCollectionLibary
7![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
8
public class People : IList
9![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
10
ArrayList _list;
11
public People()
12![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
13
_list = new ArrayList();
14
}
15![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
IList 成员#region IList 成员
16
//取决与你是否需要为People对象是否需要这个方法而定。
17
public int Add(Person value)
18![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
19
return _list.Add(value);
20
}
21
//这是接口实现必须的。
22
int IList.Add(object value)
23![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
24
//如果你实现了上面的Add方法,就可以使用直接调用以上的Add方法。
25
return this.Add((Person)value);
26
//如果你不打算让People类具有Add方法并且又要实现接口你可以使用一下的方式。
27
//return _list.Add(value);
28
}
29
//取决与你是否需要为People对象是否需要这个方法而定。
30
public void Clear()
31![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
32![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
33
_list.Clear();
34
}
35
//这是接口实现必须的。
36
void IList.Clear()
37![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
38
//理由同上。
39
this.Clear();
40
}
41
//在这里我并没有实现Contains接口方法的向对应的实例方法。
42
//表明我并不想为People类提供相应的可以通过People对象访问的方法。
43
//只能通过接口才可以访问此实现。
44
bool IList.Contains(object value)
45![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
46
47
return _list.Contains((Person)value);
48
}
49
//取决与你是否需要为People对象是否需要这个方法而定。
50
public int IndexOf(Person value)
51![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
52
return _list.IndexOf(value);
53
}
54
//这是接口实现必须的。
55
int IList.IndexOf(object value)
56![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
57
return _list.IndexOf((Person)value);
58
}
59
//取决与你是否需要为People对象是否需要这个方法而定。
60
public void Insert(int index, Person value)
61![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
62
_list.Insert(index, value);
63
}
64
//这是接口实现必须的。
65
void IList.Insert(int index, object value)
66![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
67
this.Insert(index, (Person)value);
68
}
69
//这个属性返回一个值用于指示集合的容量是否是固定的。
70
bool IList.IsFixedSize
71![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
72![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{return false; }
73
}
74
//这个属性表示集合是否是只读的。
75
bool IList.IsReadOnly
76![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
77![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return false; }
78
}
79
//你可以根据需要如上实现相应的实例的方法。
80
void IList.Remove(object value)
81![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
82
_list.Remove((Person)value);
83
}
84![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
85
void IList.RemoveAt(int index)
86![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
87
_list.RemoveAt(index);
88
}
89![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
90
object IList.this[int index]
91![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
92
get
93![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
94
return _list[index];
95
}
96
set
97![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
98
_list[index] = (Person)value;
99
}
100
}
101![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
102
#endregion
103![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
104![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
ICollection 成员#region ICollection 成员
105![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
106
void ICollection.CopyTo(Array array, int index)
107![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
108
_list.CopyTo((Person[])array, index);
109
}
110![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
111
int ICollection.Count
112![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
113![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return _list.Count; }
114
}
115![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
116
bool ICollection.IsSynchronized
117![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
118![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return _list.IsSynchronized; }
119
}
120![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
121
object ICollection.SyncRoot
122![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
123![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return _list.SyncRoot; }
124
}
125![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
126
#endregion
127![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
128![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
IEnumerable 成员#region IEnumerable 成员
129![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
130
IEnumerator IEnumerable.GetEnumerator()
131![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
132
return _list.GetEnumerator();
133
}
134![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
135
#endregion
136
}
137
}
138![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
其中需要说明的是:带IList.方法名的方法才是必须要实现的方法。如果你需要是你的类具有自己对应与接口的方法也可以如我在代码中实现的那样来实现。
最后请注意一下IEnumerable.GetEnumerator()方法。我使用的是一种简单的实现方式。如果你需要编写逻辑也可以想如下这样做。
建立一个PeopleEnumerator让它实现IEnumerator接口。
1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
using System.Collections;
5![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
6
namespace MyCollectionLibary
7![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
8![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
9
/// foreach会使用这个类对People类进行迭代。
10
/// </summary>
11
public class PeopleEnumerator : IEnumerator
12![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
13
14
private int _index;
15
private IList _list;
16
public PeopleEnumerator(IList list)
17![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
18
_index = -1;
19
_list = list;
20
}
21![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
IEnumerator 成员#region IEnumerator 成员
22
//返回当前从集合中猎取的一项。
23
object IEnumerator.Current
24![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
25![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return _list[_index]; }
26
}
27
//当foreach开始的是否最先调用这个方法。
28
//这个方法如果返回true,foreach循环会继续。
29
//如果这个方法返回false, foreach循环会结束。
30
bool IEnumerator.MoveNext()
31![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
32
_index++;
33
if (_index < _list.Count)
34
return true;
35
return false;
36
}
37
//foreach迭代停止前会调用这个方法重设相应的值。
38
void IEnumerator.Reset()
39![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
40
_index = -1;
41
}
42![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
43
#endregion
44
}
45
}
46![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
编写好这个类以后你还需要修改一下People类中的IEnumerable.GetEnumerator()的实现。实现如下:
将原有的代码删除掉,替代为:return new PeopleEnumerator(_list);
就完成了。
接下来你可以下载我完成的Demo看看测试的结果。
代码下载
完成。。。。。。。。。。。。。。。。。。。。。。