我面临的问题是,当我有一个具有默认值的属性的类时,如下所示:
public class Border {
public Border() {
InitializeAdornment();
}
[DefaultValue(true)]
public bool Visible {
get;
set;
}
private void InitializeAdornment() {
Visible = true;
// Some initialization code here that don't do anything with the property...
}
}
然后将其用作具有DesignerSerializationVisibility.Content
属性的UserControl的属性,如下所示:
public class Label : HitAbleControl, IText, IBorder {
public Label() {
InitializeAdornments();
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public Border Border {
get {
return __border;
}
set {
__border = value;
}
}
private Border __border;
private void InitializeAdornments() {
Border = new Border {
Visible = false
};
// Some initialization code here that don't do anything with the property...
}
}
如果我使用Visual Studio Designer设置label1.Border.Visible = true
,它不会被序列化,但它应该是因为在这种情况下默认值应为false而不是true。
我知道我可以将Border
类更改为始终序列化,或检查默认值是真还是假,但我想知道是否有ShouldSerialize[PropertyName]
之类的内容对于此序列化问题的属性或其他变通方法的属性,而不更改序列化程序。
我搜索了几个小时试图解决这个问题而没有吸引CodeDomSerializer
,或者至少理解为什么视觉工作室设计师不会对此进行序列化。
任何帮助将不胜感激,谢谢!
答案 0 :(得分:1)
首先让我说明没有ShouldSerialize[PropertyName]
或其他标准机制来控制嵌套对象属性的行为。
您要求的是可以完成的,但在包含的类中需要一些额外的状态。如果你没有提供公共setter可能会更简单,所以你可以传递某种所有者接口或者从Border
类调用的东西。由于这似乎不是一个选项,因此它需要一些额外的工作来克隆setter中传递的值。
重点是将默认值作为类属性,而不是静态常量。请注意,如果通过设计器或代码设置值无关紧要,则序列化程序使用DefaultValueAttribute
来确定值是否需要序列化。顺便说一句,最简单的方法可能是删除该属性,添加名为bool
的{{1}}方法并始终返回ShouldSerializeVisible
。这是一个更高级的实现:
true
请注意已移除[TypeConverter(typeof(ExpandableObjectConverter))]
public class Border
{
public Border()
{
InitializeAdornment();
}
public Border Clone() { return (Border)MemberwiseClone(); }
public bool Visible { get; set; }
private bool ShouldSerializeVisible() { return Visible != DefaultVisible; }
private void ResetVisible() { Visible = DefaultVisible; }
[Browsable(false)]
[RefreshProperties(RefreshProperties.All)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool DefaultVisible { get; set; }
private void InitializeAdornment()
{
Visible = DefaultVisible = true;
// Some initialization code here that don't do anything with the property...
}
}
并替换为私有DefaultValueAttribute
和ShouldSerialize[PropertyName]
方法以及Reset[PropertyName]
实例成员。
DefaultVisible
课程内的属性为:
Label
缺点是传递的[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public Border Border
{
get { return __border; }
set
{
if (value != null)
{
value = value.Clone();
value.DefaultVisible = false;
}
__border = value;
}
}
实例必须克隆在setter中。