集合属性相信大家都很熟悉也很常用,如DropDownList,ListBox等控件
< asp:DropDownList ID ="DropDownList1" runat ="server" > < asp:ListItem > 测试1 </ asp:ListItem > < asp:ListItem > 测试2 </ asp:ListItem > < asp:ListItem > 测试3 </ asp:ListItem > </ asp:DropDownList >
1.实现集合属性效果
经过前面几篇的学习,相信这一篇看起来已经相对简单了.我们要做的就是,先定义一个复杂属性,然后用迭代语句获取数组数据即可。如果看过前面几篇就看看下面代码吧,相信看起来很简单,我们模仿一个DropDownList,为其属性添加背景属性,代码如下
先定义一个集合属性,如下
public class DropItem { private string text; private string value; private Color backColor; [ Category("Behavior"), DefaultValue(""), Description("项文本"), NotifyParentProperty(true), ] public String Text { get { return text; } set { text = value; } } [ Category("Behavior"), DefaultValue(""), Description("项值"), NotifyParentProperty(true), ] public String Value { get { return value; } set { this.value = value; } } [ Category("Behavior"), DefaultValue(""), Description("背景颜色"), NotifyParentProperty(true), ] public Color BackColor { get { return backColor; } set { backColor = value; } } }
然后自定义一个控件,输出集合属性,如下代码
[ParseChildren( true , " DropItemList " )] public class DropColor:WebControl { private ArrayList dropItemList; [ Category( " Behavior " ), Description( " 项集合 " ), DesignerSerializationVisibility( DesignerSerializationVisibility.Content), PersistenceMode(PersistenceMode.InnerDefaultProperty), ] // 定义集合属性 public ArrayList DropItemList { get { if (dropItemList == null ) { dropItemList = new ArrayList(); } return dropItemList; } } // 重写标签 protected override HtmlTextWriterTag TagKey { get { return HtmlTextWriterTag.Select; } } protected override void RenderContents(HtmlTextWriter writer) { // 输出集合属性 foreach (DropItem item in dropItemList) { DropItem dr = item as DropItem; if (dropItemList != null && dropItemList.Count > 0 ) { // 颜色转换 WebColorConverter wcc = new WebColorConverter(); writer.AddAttribute(HtmlTextWriterAttribute.Value, dr.Value.ToString()); writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor, wcc.ConvertToString(dr.BackColor)); writer.RenderBeginTag(HtmlTextWriterTag.Option); writer.Write(dr.Text.ToString()); writer.RenderEndTag(); } } base .RenderContents(writer); } }
上面代码注意颜色类型之间的转换,以下为HTML代码
< custom:DropColor ID ="DropColor1" runat ="server" ForeColor ="White" > < custom:DropItem BackColor ="Yellow" Text ="黄色" Value ="yellow" /> < custom:DropItem BackColor ="Red" Text ="红色" Value ="red" /> < custom:DropItem BackColor ="Blue" Text ="蓝色" Value ="blue" /> < custom:DropItem BackColor ="Green" Text ="绿色" Value ="green" /> < custom:DropItem BackColor ="Black" Text ="黑色" Value ="Black" /> </ custom:DropColor >
输出以后的效果如下图
效果还不错吧,而且挺实用的.2.定义编辑器
大家一般在添加集合属性的时候往往会在.net自带的编辑器中添加数据,这样可以提高效果,不用在HTML视图添加数据.如下图
我们也可以为其添加自定义的编辑器,其实我们一直在用.net自带的编辑器,我们称之为 UI编辑器或视图编辑器,如颜色,时间,超级链接等,大家该有所体会。其编辑器的基类为位于System.Drawing.Design命名空间的UITypeEditor,很多UI编辑器都从此类派生,有兴趣的可以去了解下这个类。你们如何使用使用UI编辑器呢?也跟上一篇讲的类型转换器一样,你先要定义一个UI编辑器,然后与相关属性关联起来。因为所定义的是一个集合类,而.net已经为我们提供了一个集合编辑器的CollectionEditor类,其已经为我们做了很多工作了,我们最简单的只需重写几个方法即可.具体其他属性和方法请参考MSDN,如下代码
public class DropItemEditor : CollectionEditor { public DropItemEditor(Type type) : base(type) { } //一次可否选择多项 protected override bool CanSelectMultipleInstances() { return false; } //获取此集合包含的数据类型 protected override Type CreateCollectionItemType() { return typeof(DropItem); } }
然后把集合属性与编辑器关联起来,添加了一个EditorAttribute,第一个参数为指定的编辑器类型,第二个为基本类型
[ Category( " Behavior " ), Description( " 项集合 " ), DesignerSerializationVisibility( DesignerSerializationVisibility.Content), PersistenceMode(PersistenceMode.InnerDefaultProperty), Editor( typeof(DropItemEditor), typeof (UITypeEditor)), ] // 定义集合属性 public ArrayList DropItemList { get { if (dropItemList == null) { dropItemList = new ArrayList(); } return dropItemList; } }
然后再来看下效果,这样就方面很多了.
如果还不想看到编辑器里的CustomComponents的命名空间的话,你可以像上一篇一样自定义一个类型转换器,代码如下:
public class DropItemConverter : ExpandableObjectConverter { #region 方法 public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { if (sourceType == typeof ( string )) { return true ; } return base .CanConvertFrom(context, sourceType); } public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { if (destinationType == typeof ( string )) { return true ; } return base .CanConvertTo(context, destinationType); } public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (value == null ) { return new DropItem(); } if (value is string ) { string s = ( string )value; if (s.Length == 0 ) { return new DropItem(); } return " DropItem " ; } return base .ConvertFrom(context, culture, value); } public override object ConvertTo( ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { if (value != null ) { if ( ! (value is DropItem)) { throw new ArgumentException( " Invalid DropItem " , " value " ); } } if (destinationType == typeof ( string )) { if (value == null ) { return String.Empty; } return " DropItem " ; } return base .ConvertTo(context, culture, value, destinationType); } #endregion }
然后还是照着步骤把属性与其关联起来
[TypeConverter( typeof (DropItemConverter))] public class DropItem { }
再来看下效果
好了,这回讲的比较简单又实用,希望对大家有帮助.大家同时也可以参考MSDN里的例子,下面的示例代码下载我也加上了MSDN的例子。已经写了10篇了,我们应该有些基础了,我想大家该可以做出一些简单实用的控件了。