属性不会被序列化到.designer.cs文件中

时间:2010-06-28 19:08:52

标签: c# visual-studio-2010 serialization designer

在VS2010中,尽管使用了ShouldSerializeFoo方法,控制属性也不会被序列化,同时还有DesignerSerializationVisibility.Visible / Content。

以下是代码:

class Class1 : UserControl {
    [Browsable(true)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public string Foo {
        get; set;
    }
    public bool ShouldSerializeFoo() {
        return true;
    }
    public Class1() {
        Foo = "dupa";
    }
}

但是,设计人员不会为此属性生成任何内容:

        // 
        // class11
        // 
        this.class11.Location = new System.Drawing.Point(224, 262);
        this.class11.Name = "class11";
        this.class11.Size = new System.Drawing.Size(150, 150);
        this.class11.TabIndex = 2;
        this.class11.Load += new System.EventHandler(this.class11_Load);

1 个答案:

答案 0 :(得分:9)

您正在混合序列化方案。设计器序列化(这是DesignerSerializationVisibility的用途)与实例序列化机制无关(这是ShouldSerializeXXX函数,以及许多其他事项处理)。

对于DesignerSerializationVisibility.Content(或任何其他不可变类型),

string没有多大意义。设计人员可以将属性的序列化视为三种类型:

  • 无 - 它从不序列化有关该属性的任何内容
  • 可见 - 它将序列化属性的实际值
  • 内容 - 它将序列化属性值的属性值

默认情况下,属性被视为Visible。我意识到我对Content的定义可能有点令人困惑。我的意思是这样的:

public class MyControl : Control
{
    public class SomeOptions
    {
        public string Option1 { get; set; }
        public string Option2 { get; set; }
    }

    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public SomeOptions Options { get; private set; }

    public string Foo { get; set; }
}

现在,当这个类被设计者序列化时,它看起来像这样:

// myControl1
this.myControl1.Foo = "value";
this.myControl1.Options.Option1 = "option1";
this.myControl1.Options.Option2 = "option2";

这应该更有意义;将属性标记为Content表示,不是序列化属性的实际值(在这种情况下,它将是SomeOptions的实例),它应该序列化取而代之的是该值的属性值。

所以,回到你的问题,这就是你不希望Content属性为string的原因。因为string是不可变的,所以设计器没有任何序列化。将其标记为Visible或完全取消该属性(因为这是默认设置)。

虽然可以向设计者提供关于是否要序列化特定属性的自定义方向,但这是一个非常复杂(和讨厌)的过程。但是, easy 方法是使用属性上的DefaultValue属性。如果属性是否应序列化,可以通过将其值与常量进行比较来确定(换句话说,它不依赖于运行时的任何其他内容,如另一个属性的值),您可以像这样装饰属性:< / p>

[DefaultValue("foo")]
public string Foo { get; set; }

如果设计师发现Foo的值等于"foo",那么它根本不会序列化该属性。