未在设计器中序列化派生的集合属性

时间:2018-11-07 09:05:02

标签: c# .net winforms windows-forms-designer

我有一个类,该类派生自具有MyString属性的集合,即

  public class CollectionItem
  {
    public bool MyBoolean { get; set; }

    public int MyInteger { get; set; }
  }

  public class MyCollection : List<CollectionItem>
  {
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
    public string MyString { get; set; }

    public MyCollection()
    {
      MyString = "Hello";
    }
  }

此集合是简单的DummyControl的一部分,即

  public class DummyControl : System.Windows.Forms.Control
  {
    protected override void OnPaint(PaintEventArgs e)
    {
      base.OnPaint(e);
      e.Graphics.FillRectangle(System.Drawing.Brushes.Yellow, e.ClipRectangle);
    }

    public DummyControl() 
    {
      MyCollection = new MyCollection();

      for (int i = 0; i < 3; i++)
      {
        CollectionItem item = new CollectionItem();
        item.MyInteger = i;
        item.MyBoolean = i > 1;
        MyCollection.Add(item);
      }
    }

    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public MyCollection MyCollection { get; set; }
  }

当我将此DummyControl放在Windows窗体上时,除MyString属性外,所有内容均按预期方式序列化到窗体设计器中-这就是我得到的:

  // 
  // dummyControl1
  // 
  this.dummyControl1.Location = new System.Drawing.Point(66, 62);
  collectionItem1.MyBoolean = false;
  collectionItem1.MyInteger = 0;
  collectionItem2.MyBoolean = false;
  collectionItem2.MyInteger = 1;
  collectionItem3.MyBoolean = true;
  collectionItem3.MyInteger = 2;
  this.dummyControl1.MyCollection.Add(collectionItem1);
  this.dummyControl1.MyCollection.Add(collectionItem2);
  this.dummyControl1.MyCollection.Add(collectionItem3);
  this.dummyControl1.Name = "dummyControl1";
  this.dummyControl1.Size = new System.Drawing.Size(338, 266);
  this.dummyControl1.TabIndex = 0;
  this.dummyControl1.Text = "dummyControl1";

有人可以告诉我,要把MyString属性序列化到表单设计器还要做什么?

1 个答案:

答案 0 :(得分:1)

默认CodeDom集合序列化程序不会序列化集合的属性。您可以通过衍生自CodeDomSerializer来创建自定义序列化程序。然后为您的课程注册自定义序列化程序:

[DesignerSerializer(typeof(MyCollectionSerializer), typeof(CodeDomSerializer))]
public class MyCollection : List<CollectionItem>

MyCollectionSerializer

此序列化程序序列化MyString的{​​{1}}属性:

MyCollection

然后using System.CodeDom; using System.ComponentModel; using System.ComponentModel.Design.Serialization; public class MyCollectionSerializer : CodeDomSerializer { public override object Serialize(IDesignerSerializationManager manager, object value) { var baseSerializer = (CodeDomSerializer)manager.GetSerializer( typeof(MyCollection).BaseType, typeof(CodeDomSerializer)); var statements = (CodeStatementCollection)baseSerializer.Serialize(manager, value); var property = TypeDescriptor.GetProperties(value)[nameof(MyCollection.MyString)]; if (property.ShouldSerializeValue(value)) { var targetObject = base.GetExpression(manager, value); var cpre = new CodePropertyReferenceExpression(targetObject, property.Name); var cpe = new CodePrimitiveExpression(property.GetValue(value)); var cas = new CodeAssignStatement(cpre, cpe); statements.Add(cas); } return statements; } } 属性也将被序列化:

MyString