这个问题前段时间我答过,可以看我的回答
http://community.csdn.net/Expert/TopicView.asp?id=2968427如果需要还可以贴出全部代码,不过要分两贴了:)

解决方案 »

  1.   

    to:micropentium6(小笨)
    能再贴出全部代码吗。谢谢
      

  2.   

    呵呵,那个帖子里有部分代码的:)
    以form控件为例子,下面的代码是一个基类,你可以将该类作为基类,试着在设计器的propertygrid中改写items属性并添加content子项,并用一个al作为对比,观察不同结果
    下面分几贴贴出基类代码using System;
    using System.Drawing;
    using System.Collections;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.ComponentModel.Design.Serialization;
    using System.Reflection;
    namespace Collection
    {
    /// <summary>
    /// Base 的摘要说明。
    /// </summary>
    public class Base : System.Windows.Forms.Form
    {
    /// <summary>
    /// 必需的设计器变量。
    /// </summary>
    private System.ComponentModel.Container components = null;
            public System.Collections.ArrayList collection=null;
    private Collection.BaseCollections itemCollections=null;
    public Base()
    {
    //
    // Windows 窗体设计器支持所必需的
    //
    InitializeComponent(); //
    // TODO: 在 InitializeComponent 调用后添加任何构造函数代码
    //
    collection=new ArrayList();
    } /// <summary>
    /// 清理所有正在使用的资源。
    /// </summary>
    protected override void Dispose( bool disposing )
    {
    if( disposing )
    {
    if(components != null)
    {
    components.Dispose();
    }
    }
    base.Dispose( disposing );
    } #region Windows 窗体设计器生成的代码
    /// <summary>
    /// 设计器支持所需的方法 - 不要使用代码编辑器修改
    /// 此方法的内容。
    /// </summary>
    private void InitializeComponent()
    {
    this.components = new System.ComponentModel.Container();
    this.Size = new System.Drawing.Size(300,300);
    this.Text = "Base";
    }
    #endregion
    [Category("Appearence"),MergableProperty(false), Localizable(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public BaseCollections Items
    {
    get
    {
    if(this.itemCollections==null)
    itemCollections=new BaseCollections(this);
    return itemCollections;
    }
    }
    private ArrayList al;
    [Category("Appearence"),DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public ArrayList AL
    {
    get
    {
    if(al==null)
                        al=new ArrayList();
    return al;
    }
    set
    {
    al=value;
    }
    }

    }
      

  3.   

    public class ContentConvert:System.ComponentModel.ExpandableObjectConverter
    {
    public ContentConvert()
    {
    }

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
    // TODO:  添加 ContentConvert.CanConvertTo 实现
    if(destinationType==typeof(InstanceDescriptor))
    {
    return true;
    }
    return base.CanConvertTo (context, destinationType);
    }

    public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
    {
    // TODO:  添加 ContentConvert.ConvertTo 实现
    //Type[] array1;
    //object[] array2;
    ConstructorInfo info1;
    Content item;
    if(destinationType==null)
    throw new System.ArgumentNullException("destinationType is null");
    if(destinationType==typeof(InstanceDescriptor)&&(value as Content)!=null)
    {
    item=value as Content;
    //array1=new Type[1];
    //array1[0]=typeof(string);
    info1=typeof(Content).GetConstructor(System.Type.EmptyTypes);
    if(info1==null)
    {
    throw new System.ArgumentNullException("info1");

    }

    //array2=new object[1];
    //array2[0]=item.Str;
                    return new InstanceDescriptor(info1,System.Type.EmptyTypes,false);
    }
    return base.ConvertTo (context, culture, value, destinationType);
    }
    }
    [Serializable,TypeConverter(typeof(ContentConvert))]
    public class Content:System.ICloneable,System.Runtime.Serialization.ISerializable
    {
    private string str;
    [Category("Appearence")]//,DesignerSerializationVisibility(DesignerSerializationVisibility.Content),Browsable(true)]
    public string Str
    {
    get
    {
    return str;
    }
    set
    {
    if(TypeDescriptor.GetConverter(typeof(string)).IsValid(value))
    {
    str=value;
    }
    }
    }
    public Content()
    {
    str=string.Empty;
    }
    private Content(System.Runtime.Serialization.SerializationInfo info,System.Runtime.Serialization.StreamingContext context)
    {
    System.Runtime.Serialization.SerializationInfoEnumerator enumerator=info.GetEnumerator();
    while(enumerator.MoveNext())
    {
    System.Runtime.Serialization.SerializationEntry entry=enumerator.Current;
    if(entry.Name=="Str")
    {
    this.str=((string)entry.Value);
    continue;
    }
    }
    }
    /*protected override void Dispose(bool disposing)
    {
    // TODO:  添加 Content.Dispose 实现
    base.Dispose (disposing);
    }*/ #region ICloneable 成员 public virtual object Clone()
    {
    // TODO:  添加 Content.Clone 实现
    Content item=null;
    Type type=base.GetType();
    if(typeof(Content)==type)
    {
    item=new Content();

    }
    else
    {
    item=((Content)Activator.CreateInstance(type));
    }
    item.Str=this.str;
    return item;
    } #endregion #region ISerializable 成员 public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
    {
    // TODO:  添加 Content.GetObjectData 实现
    info.AddValue("Str",str);
    } #endregion
    }
      

  4.   

    可能太长贴不完,我只能连续发三个帖子,你自己up一下,我接着发
    public class BaseCollections:System.Collections.IList
    {

    private Base owner;
    public BaseCollections(Base frm)
    {
    owner=frm;
    }
    public virtual int Add(Content value)
    {
    // TODO:  添加 BaseCollections.Add 实现
    int num1=this.owner.collection.Count;
    this.owner.collection.Add(value);
    return num1;
    }
    int System.Collections.IList.Add(object value)
    {
    //if((value as string)!=null)
    //{
    Content c=value as Content;
    if(c!=null)
    return this.Add(c);
    else
    {

    return 0;
    }
                    
    //}
                //throw new System.ArgumentException("add:value");
    }
    public virtual void Clear()
    {
    // TODO:  添加 BaseCollections.Clear 实现
                this.owner.collection.Clear();
    }

    public virtual bool Contains(Content value)
    {
    // TODO:  添加 BaseCollections.Contains 实现
    if(this.owner.collection.Contains(value))
    return true;
    else
        return false;
    }
    bool System.Collections.IList.Contains(object value)
    {
    //if((value as string)!=null)
    //{
    Content c=value as Content;
    if(c!=null)
    return this.Contains(c);
    else
    return false;
    //}
    //throw new System.ArgumentException("contains:value");
    }
    public virtual int IndexOf(Content value)
    {
    // TODO:  添加 BaseCollections.IndexOf 实现
    return this.owner.collection.IndexOf(value);
    }
    int System.Collections.IList.IndexOf(object value)
    {
    //if((value as string)!=null)
    //{
    Content c=value as Content;
    if(c!=null)
        return this.IndexOf(c);
    else
    return -1;
    //}
    //throw new System.ArgumentException("indexof:value");
    }
    public virtual void Insert(int index, Content value)
    {
    // TODO:  添加 BaseCollections.Insert 实现

    if(value==null)
    throw new System.ArgumentException("insert2:value");
    int num1=this.owner.Items.Count;
    if((index<0)||(index>num1))
    {
    throw new System.ArgumentOutOfRangeException("Invalid argument"+"index "+index.ToString());
    }
            this.owner.collection.Insert(index,value);
            
                
    }
    void System.Collections.IList.Insert(int index, object value)
    {
    //if((value as string)!=null)
    //{
    Content c=value as Content;
    if(c!=null)
    {
    this.Insert(index,c);
    return;
    }

    //}
    throw new System.ArgumentException("insert1:value");
    } public virtual void Remove(Content value)
    {
    // TODO:  添加 BaseCollections.Remove 实现
    this.owner.collection.Remove(value); }
    void System.Collections.IList.Remove(object value)
    {
    //if((value as string)!=null)
    //{
    Content c=value as Content;
    if(c!=null)
    {
    this.Remove(c);
    return;
    }
    //}
    throw new System.ArgumentException("remove:value"); }
    public virtual void RemoveAt(int index)
    {
    // TODO:  添加 BaseCollections.RemoveAt 实现
    int num1=this.Count;
    if((index<0)||(index>=num1))
    throw new System.ArgumentOutOfRangeException("Invalid argument "+"index "+index.ToString());
                this.owner.collection.RemoveAt(index);
    }
        public bool IsFixedSize
    {
    get
    {
    // TODO:  添加 BaseCollections.IsFixedSize getter 实现
    return false;
    }
    }
    public bool IsReadOnly
    {
    get
    {
    // TODO:  添加 BaseCollections.IsReadOnly getter 实现
    return false;
    }
    }

    public virtual Content this[int index]  //设计器通过自己重载的this[]来确定集合元素的类型?
    {
    get
    {
    // TODO:  添加 BaseCollections.this getter 实现
    int num1=this.Count;
    if((index<0)||(index>=num1))
    throw new System.ArgumentOutOfRangeException("Invalid argument "+"index "+index.ToString());
    return this.owner.collection[index] as Content;
    }
    set
    {
    // TODO:  添加 BaseCollections.this setter 实现
    int num1=this.Count;
    if((index<0)||(index>=num1))
    throw new System.ArgumentOutOfRangeException("Invalid argument "+"index "+index.ToString());
    MessageBox.Show(value.Str);
    this.owner.collection[index]=value;
    }
    }
    object System.Collections.IList.this[int index]
    {
    get
    {
    return this[index];
    }
    set
    {
    if((value as Content)!=null)
        this[index]=(Content)value;
    }
    }
    public void CopyTo(Array array, int index)
    {
    // TODO:  添加 BaseCollections.CopyTo 实现
                this.owner.collection.CopyTo(array,index);
    }

    public bool IsSynchronized
    {
    get
    {
    // TODO:  添加 BaseCollections.IsSynchronized getter 实现
    return false;
    }
    }

    public object SyncRoot
    {
    get
    {
    // TODO:  添加 BaseCollections.SyncRoot getter 实现
    return null;
    }
    }

    public IEnumerator GetEnumerator()
    {
    // TODO:  添加 BaseCollections.GetEnumerator 实现
    return this.owner.collection.GetEnumerator();
    }

    public int Count
    {
    get
    {
    // TODO:  添加 BaseCollections.Count getter 实现
    return this.owner.collection.Count;
    }
    }
    }

    }
      

  5.   

    http://www.codeproject.com/cs/combobox/imagelistbox.asp实现Item类,实现ItemCollection类,然后加
    [DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Content )]
      

  6.   

    呵呵,楼上大哥说的对,很多地方都有代码,不过我写的时候的确没有参考人家的代码,我是用的reflector:)下面是继承自Base类的代码,注意窗体设计器自动生成的代码,item和al的对比:
    using System;
    using System.Drawing;
    using System.Collections;
    using System.ComponentModel;
    using System.Windows.Forms;namespace Collection
    {
    /// <summary>
    /// Inherit 的摘要说明。
    /// </summary>
    public class Inherit : Collection.Base
    {
    /// <summary>
    /// 必需的设计器变量。
    /// </summary>
    private System.ComponentModel.Container components = null; public Inherit()
    {
    //
    // Windows 窗体设计器支持所必需的
    //
    InitializeComponent(); //
    // TODO: 在 InitializeComponent 调用后添加任何构造函数代码
    //
    } /// <summary>
    /// 清理所有正在使用的资源。
    /// </summary>
    protected override void Dispose( bool disposing )
    {
    if( disposing )
    {
    if(components != null)
    {
    components.Dispose();
    }
    }
    base.Dispose( disposing );
    } #region Windows 窗体设计器生成的代码
    /// <summary>
    /// 设计器支持所需的方法 - 不要使用代码编辑器修改
    /// 此方法的内容。
    /// </summary>
    private void InitializeComponent()
    {
    System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(Inherit));
    Collection.Content content1 = new Collection.Content();
    Collection.Content content2 = new Collection.Content();
    Collection.Content content3 = new Collection.Content();
    // 
    // Inherit
    // 
    this.AL.Add(((System.Collections.ICollection)(resources.GetObject("resource"))));
    this.AL.Add(((System.Collections.ICollection)(resources.GetObject("resource1"))));
    this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
    this.ClientSize = new System.Drawing.Size(292, 266);
    content1.Str = "a";
    content2.Str = "b";
    content3.Str = "d";
    this.Items.Add(content1);
    this.Items.Add(content2);
    this.Items.Add(content3);
    this.Name = "Inherit";
    this.Text = "Inherit"; }
    #endregion
    }
    }
      

  7.   

    micropentium6(小笨) :
    能不能把那些变量的声明放到外面去呢
    Collection.Content content1 = new Collection.Content();
    Collection.Content content2 = new Collection.Content();
    Collection.Content content3 = new Collection.Content();
    他们只属于InitializeComponent()方法的内部变量呀
    谢谢
      

  8.   

    如果Content是控件的成员变量的话,用这种方法是不行的。但这里没有什么局部变量的问题,由于集合保存了Content实例的引用,因此你不能象C语言那样把它看做局部变量,因为.NET下的变量生存期是由GC决定的。