示例代码
让我们回头看第10篇随笔,很简单的写了下集合属性的使用,这次再深入些的讨论关于集合相关的应用
一.定义对象集合类型
public
DropItems ItemList
{
get
{
if (_items == null)
{
_items = new DropItems();
}
return _items;
}
}
在后台使用ItemList属性操作的时候,假设是Add操作,则里面的对象则是一个object,当然也可以,ArrayList什么都可以扔,但每一次类型的转换,明显的降低了效率.所以我们需要为其定义集合类型.如下定义
public class DropItems : CollectionBase
{
private ArrayList _itemArrayList;
public DropItems()
{
_itemArrayList = new ArrayList();
}
public void Add(DropItem _item)
{
List.Add(_item);
}
public void Remove(DropItem _item)
{
List.Remove(_item);
}
public new int Count
{
get
{
return List.Count;
}
}
public DropItem this[int index]
{
get
{
return (DropItem)_itemArrayList[index];
}
}
}
然后在控件中把集合属性类型换成DropItems
public
DropItems ItemList
{
get
{
if (_items == null)
{
_items = new DropItems();
}
return _items;
}
}
定义集合类型的起点很多,上面代码从CollectionBase继承,你也可以继承Ilist等接口,不过这样比较麻烦,要写很多方法. .net2.0的泛型类提供了新的起点,System.Collections.ObjectModel.Collection泛型类.我们可以从这个类开始,将会节省很多的时间的.
二.单集合多子类型
相信大家熟悉asp.net2.0中的ImageMap控件,里面有一个
HotSpot集合属性,提供作用点集合,但作用点又分圆形,矩形,和多边行
难道我们要为控件定义三个集合类型?由于这三个作用点区域对象有很多的相似性,所以没有必要。我们只需要为其一个基类,三个子类,一个集合类就可以了.
我们来模仿着做
(1)定义button对象
public abstract class BaseButton
{
private string _text;
public string Text
{
get
{
return _text;
}
set
{
_text=value;
}
}
}
public class MyButton : BaseButton
{
}
public class ImageButton : BaseButton
{
private string _imageurl;
public string ImageUrl
{
get
{
return _imageurl;
}
set
{
_imageurl = value;
}
}
}
(2)定义对象集合类型
上面说过了, 你可以从泛型类开始,可以节省很多工作,不然你也可以继承CollectionBase,注意,注释部分为继承CollectionBase的实现,从泛型类开始则一行代码也不需要写,自己选吧
public class ButtonCollection : Collection<BaseButton>
{
//private ArrayList _itemArrayList;
//public ButtonCollection()
//{
// _itemArrayList = new ArrayList();
//}
//public void Add(BaseButton _item)
//{
// List.Add(_item);
//}
//public void Remove(BaseButton _item)
//{
// List.Remove(_item);
//}
//public new int Count
//{
// get
// {
// return List.Count;
// }
//}
//public BaseButton this[int index]
//{
// get
// {
// return (BaseButton)_itemArrayList[index];
// }
//}
}
(3)定义集合属性
[PersistenceMode(PersistenceMode.InnerDefaultProperty),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
Category(
"
Behavior
"
)]
public
ButtonCollection Buttons
{
get
{
if (this._buttons == null)
{
this._buttons = new ButtonCollection();
}
return this._buttons;
}
}
注意有些元数据特性的使用非常的重要,一定要会用.如
PersistenceMode.InnerDefaultProperty,为默认内镶属性
接着就可以在页面使用了,如下,注意到没,可以存在两种集合属性了,其实只是一种.
<
aspDemo:TestControl ID
=
"
TestControl1
"
runat
=
"
server
"
Buttons
-
Capacity
=
"
4
"
>
<
aspDemo:MyButton Text
=
"
aa
"
/>
<
aspDemo:MyButton Text
=
"
bbb
"
/>
<
aspDemo:ImageButton ImageUrl
=
"
image.jpg
"
Text
=
"
fasdfa
"
/>
<
aspDemo:ImageButton ImageUrl
=
"
image.jpg
"
Text
=
"
fasdfa
"
/>
<
aspDemo:MyButton Text
=
"
aa
"
/>
<
aspDemo:ImageButton ImageUrl
=
"
image.jpg
"
Text
=
"
fasdfa
"
/>
</
aspDemo:TestControl
>
(4)定义编辑器
集合属性当然少不了集合编辑器了,上面的截图大家也已经看到了,如何实现呢?
还是从CollectionEditor对象继承
以前已经认识过CreateCollectionItemType方法了,这次则是CreateNewItemTypes方法,其可以返回编辑器可以编辑的类型,因为我们要编辑的对象有MyButton和ImageButton,所以如下定义
protected
override
Type[] CreateNewItemTypes()
{
return new Type[] { typeof(MyButton), typeof(ImageButton) };
}
然后与集合类型关联起来,这样就算完成了.再看下效果,是不是方便多了
三.多集合属性控件
上面的以子对象作集合类型,很适合控件单集合属性的使用,如果有多个集合属性,上面这样的做法就会感觉非常的乱.看看asp.net ajax里的ScriptManager是如何做的,如下
<
asp:ScriptManager
ID
="ScriptManager1"
runat
="server"
>
<
Scripts
>
<asp:ScriptReference />
<asp:ScriptReference />
</
Scripts
>
<
Services
>
<
asp:ServiceReference
/>
</
Services
>
</
asp:ScriptManager
>
这里真正需要将集合属性进行分类, 上面的做法不错
做法如下
(1)定义集合类型
public
class
ImageButtonCollection : Collection
<
ImageButton
>
{
}
public
class
MyButtonCollection : Collection
<
MyButton
>
{
}
(2)作为属性使用,注意这里PersistenceMode定义为InnerProperty
[PersistenceMode(PersistenceMode.InnerProperty),
DesignerSerializationVisibility(
DesignerSerializationVisibility.Content), Category(
"
Behavior
"
)]
public
ImageButtonCollection Images
{
get
{
if (this._images == null)
{
this._images = new ImageButtonCollection();
}
return this._images;
}
}
[PersistenceMode(PersistenceMode.InnerProperty),
DesignerSerializationVisibility(
DesignerSerializationVisibility.Content), Category(
"
Behavior
"
)]
public
MyButtonCollection MyButtons
{
get
{
if (this._mybtn == null)
{
this._mybtn = new MyButtonCollection();
}
return this._mybtn;
}
}
现在页面标记如下,清晰很多.
<
aspDemo:TestControl
ID
="TestControl1"
runat
="server"
>
<
Buttons
>
<
aspDemo:ImageButton
/>
<
aspDemo:MyButton
/>
</
Buttons
>
<
Images
>
<
aspDemo:ImageButton
/>
</
Images
>
<
MyButtons
>
<
aspDemo:MyButton
/>
</
MyButtons
>
</
aspDemo:TestControl
>
四.对象集合类型
如Table控件,先是
TableRowCollection,然后是
TableCellCollection.
再如 Tree控件,他可以无限的镶套对象,如下图
原理相同,在对象中定义集合类型
public
class
MyButton : BaseButton
{
private MyButtonCollection _mybtn;
[PersistenceMode(PersistenceMode.InnerProperty),
DesignerSerializationVisibility(
DesignerSerializationVisibility.Content), Category("Behavior")]
public MyButtonCollection MyButtons
{
get
{
if (this._mybtn == null)
{
this._mybtn = new MyButtonCollection();
}
return this._mybtn;
}
}
}
以上为具有集合属性控件的常用方法.说错了还请多指教.