集合属性相信大家都很熟悉也很常用,如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篇了,我们应该有些基础了,我想大家该可以做出一些简单实用的控件了.