List designer serialization

2019-06-07 07:55发布

问题:

Why MyIntList property below correctly interprets the DesignerSerializationVisibility.Content producing the following output in the designer:

 this.myControl1.MyIntList.Add(1);
 this.myControl1.MyIntList.Add(2);
 this.myControl1.MyIntList.Add(3);

while MyClassIntList one outputs the following?

this.myButton1.MyClassIntList = new MyClass(((System.Collections.Generic.List<int>)(resources.GetObject("myControl1.MyClassIntList"))));

Here is custom control class source code:

[Serializable]
public class MyControl : Control
{
    public MyControl()
        : base()
    {
    }

    private List<int> myIntList = new List<int>(new int[] { 1, 2, 3 });

    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public List<int> MyIntList
    {
        get { return myIntList; }
        set { myIntList = value; }
    }

    internal bool ShouldSerializeMyIntList()
    {
        return true;
    }

    private MyClass myClassIntList = new MyClass(new List<int>(new[] { 1, 2, 3 }));

    public MyClass MyClassIntList
    {
        get { return myClassIntList; }
        set { myClassIntList = value; }
    }

    internal bool ShouldSerializeMyClassIntList()
    {
        return true;
    }

}

Here is the complete Form1.cs source code, in the case you want to test it:

public partial class MyForm : Form
{
    public MyForm()
    {
        InitializeComponent();
    }
}

[Serializable]
public class MyControl : Control
{
    public MyControl()
        : base()
    {
    }

    private List<int> myIntList = new List<int>(new int[] { 1, 2, 3 });

    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public List<int> MyIntList
    {
        get { return myIntList; }
        set { myIntList = value; }
    }

    internal bool ShouldSerializeMyIntList()
    {
        return true;
    }

    private MyClass myClassIntList = new MyClass(new List<int>(new[] { 1, 2, 3 }));

    public MyClass MyClassIntList
    {
        get { return myClassIntList; }
        set { myClassIntList = value; }
    }

    internal bool ShouldSerializeMyClassIntList()
    {
        return true;
    }

}

[Serializable, TypeConverter(typeof(MyClassConverter))]
public class MyClass
{
    public MyClass(List<int> list)
    {
        myIntList = list;
    }

    private List<int> myIntList = new List<int>(new int[] { 1, 2, 3 });

    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public List<int> MyIntList
    {
        get { return myIntList; }
        set { myIntList = value; }
    }
}

class MyClassConverter : ExpandableObjectConverter
{

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        if (destinationType == typeof(InstanceDescriptor))
            return true;
        return base.CanConvertTo(context, destinationType);
    }

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        if (value is MyClass)
        {

            if ((destinationType == typeof(InstanceDescriptor)))
            {
                MyClass myClass = (MyClass)value;

                object[] properties = new object[1];
                Type[] types = new Type[1];

                types[0] = typeof(List<int>);
                properties[0] = myClass.MyIntList;

                ConstructorInfo ci = typeof(MyClass).GetConstructor(types);
                return new InstanceDescriptor(ci, properties);
            }

        }

        return base.ConvertTo(context, culture, value, destinationType);
    }

    public override bool GetCreateInstanceSupported(ITypeDescriptorContext context)
    {
        return true;
    }

    public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues)
    {
        return new MyClass((List<int>)propertyValues["MyIntList"]);
    }

}