在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);
答案 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"
,那么它根本不会序列化该属性。