示例代码
让我们回头看第10篇随笔,很简单的写了下集合属性的使用,这次再深入些的讨论关于集合相关的应用
一.定义对象集合类型
public DropItems ItemList
{
get
{
if (_items == null)
{
_items = new DropItems();
}
return _items;
}
}
{
get
{
if (_items == null)
{
_items = new DropItems();
}
return _items;
}
}
在后台使用ItemList属性操作的时候,假设是Add操作,则里面的对象则是一个object,当然也可以,ArrayList什么都可以扔,但每一次类型的转换,明显的降低了效率.所以我们需要为其定义集合类型.如下定义
然后在控件中把集合属性类型换成DropItems
public DropItems ItemList
{
get
{
if (_items == null)
{
_items = new DropItems();
}
return _items;
}
}
{
get
{
if (_items == null)
{
_items = new DropItems();
}
return _items;
}
}
定义集合类型的起点很多,上面代码从CollectionBase继承,你也可以继承Ilist等接口,不过这样比较麻烦,要写很多方法. .net2.0的泛型类提供了新的起点,System.Collections.ObjectModel.Collection泛型类.我们可以从这个类开始,将会节省很多的时间的.
二.单集合多子类型
相信大家熟悉asp.net2.0中的ImageMap控件,里面有一个HotSpot集合属性,提供作用点集合,但作用点又分圆形,矩形,和多边行
难道我们要为控件定义三个集合类型?由于这三个作用点区域对象有很多的相似性,所以没有必要。我们只需要为其一个基类,三个子类,一个集合类就可以了.
我们来模仿着做
(1)定义button对象
(2)定义对象集合类型
上面说过了, 你可以从泛型类开始,可以节省很多工作,不然你也可以继承CollectionBase,注意,注释部分为继承CollectionBase的实现,从泛型类开始则一行代码也不需要写,自己选吧
(3)定义集合属性
[PersistenceMode(PersistenceMode.InnerDefaultProperty),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
Category("Behavior")]
public ButtonCollection Buttons
{
get
{
if (this._buttons == null)
{
this._buttons = new ButtonCollection();
}
return this._buttons;
}
}
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>
<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) };
}
{
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>
<Scripts>
<asp:ScriptReference />
<asp:ScriptReference />
</Scripts>
<Services>
<asp:ServiceReference />
</Services>
</asp:ScriptManager>
这里真正需要将集合属性进行分类, 上面的做法不错
做法如下
(1)定义集合类型
public class ImageButtonCollection : Collection<ImageButton>
{
}
public class MyButtonCollection : Collection<MyButton>
{
}
{
}
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;
}
}
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>
<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;
}
}
}
{
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;
}
}
}
以上为具有集合属性控件的常用方法.说错了还请多指教.