有没有办法使用" ShouldSerialize [PropertyName]"关于财产的财产?

时间:2016-03-29 09:34:36

标签: c# winforms visual-studio serialization windows-forms-designer

我面临的问题是,当我有一个具有默认值的属性的类时,如下所示:

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,或者至少理解为什么视觉工作室设计师不会对此进行序列化。

任何帮助将不胜感激,谢谢!

1 个答案:

答案 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... } } 并替换为私有DefaultValueAttributeShouldSerialize[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中。