Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent Size property from being serialized when it's equal to default value

I'm trying to create my own class from System.Windows.Forms.Button

public class MyButton : Button
{

    public MyButton() : base()
    {
        Size = new Size(100, 200);
    }

    [DefaultValue(typeof(Size), "100, 200")]
    public new Size Size { get => base.Size; set => base.Size = value; }
}

I have a problem with Designer.cs behavior - default value is not working properly.

I expect, that when MyButton is added to form, it has Size of 100x200, but it is not set through Designer.cs, so when in MyButton constructor I change Size to 200x200 (also for DefaultValue) all MyButton get new size. Of course, when I change the size in Design Mode it should then be added to Designer.cs and not affected by later changes in MyButton class.

Although, in current configuration Size is always added to Designer.cs.

I tried different approaches (with Invalidate() or DesignerSerializationVisibility) but with no luck.

I want to Stop Size from being serialized when it is equal to DefaultValue. For example when it is dropped from toolbox to form - it is instantly serialized in designer, while I don't want that - only serialize when I change the size.

like image 945
Pm Duda Avatar asked Aug 09 '18 17:08

Pm Duda


People also ask

How can you prevent a property from being serialized?

You can prevent member variables from being serialized by marking them with the NonSerialized attribute as follows. If possible, make an object that could contain security-sensitive data nonserializable. If the object must be serialized, apply the NonSerialized attribute to specific fields that store sensitive data.

How do I set default value in property?

Right-click the control that you want to change, and then click Properties or press F4. Click the All tab in the property sheet, locate the Default Value property, and then enter your default value. Press CTRL+S to save your changes.


1 Answers

For some reason, the ControlDesigner replaces Size property in the PreFilterProperties with a custom property descriptor which its ShouldSerializeValue always returns true. It means the Size property will be always serialized unless you decorate it with designer serialization visibility attribute having hidden as value.

You can change the behavior by restoring the original property descriptor:

using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.Design;

[Designer(typeof(MyButtonDesigner))]
public class MyButton : Button
{
    protected override Size DefaultSize
    {
        get { return new Size(100, 100); }
    }

    //Optional, just to enable Reset context menu item
    void ResetSize()
    {
        Size = DefaultSize;
    }
}
public class MyButtonDesigner : ControlDesigner
{
    protected override void PreFilterProperties(IDictionary properties)
    {
        var s = properties["Size"];
        base.PreFilterProperties(properties);
        properties["Size"] = s;
    }
}
like image 137
Reza Aghaei Avatar answered Sep 22 '22 10:09

Reza Aghaei