I am using DefaultValue attribute for the proper PropertyGrid behavior (it shows values different from default in bold). Now if I want to serialize
I believe what you are looking for is ShouldSerialize() and Reset(). Using these will expand your class a bit more (with two functions per property), however, it achieves specifically what you are looking for.
Here's a quick example:
// your property variable
private const String MyPropertyDefault = "MyValue";
private String _MyProperty = MyPropertyDefault;
// your property
// [DefaultValueAttribute("MyValue")] - cannot use DefaultValue AND ShouldSerialize()/Reset()
public String MyProperty
{
get { return _MyProperty; }
set { _MyProperty = value; }
}
// IMPORTANT!
// notice that the function name is "ShouldSerialize..." followed
// by the exact (!) same name as your property
public Boolean ShouldSerializeMyProperty()
{
// here you would normally do your own comparison and return true/false
// based on whether the property should be serialized, however,
// in your case, you want to always return true when serializing!
// IMPORTANT CONDITIONAL STATEMENT!
if (!DesignMode)
return true; // always return true outside of design mode (is used for serializing only)
else
return _MyProperty != MyPropertyDefault; // during design mode, we actually compare against the default value
}
public void ResetMyProperty()
{
_MyProperty = MyPropertyDefault;
}
Note that because you want to keep the PropertyGrid functionality in tact, you must know whether you are serializing or not when the ShouldSerialize() function is called. I suggest you implement some sort of control flag that gets set when serializing, and thus always return true.
Please note that you cannot use the DefaultValue attribute in conjunction with the ShouldSerialize() and Reset() functions (you only use either or).
Edit: Adding clarification for the ShouldSerialize() function.
Because there is currently no way to serialize a default value and let the PropertyGrid know that a property has its default value, you must implement a condition checking whether you are in design mode.
Assuming your class derives from a Component or Control, you have a DesignMode property which is set by Visual Studio at design time only. The condition looks as follows:
if (!DesignMode)
return true; // always return true outside of design mode (is used for serializing only)
else
return _MyProperty != MyPropertyDefault; // during design mode, we actually compare against the default value
Edit 2: We're not talking about Visual Studio's design mode.
With the above code in mind, create another property called IsSerializing. Set the IsSerializing property to true before calling XmlSerializer.Serialize, and unset it after.
Finally, change the if (!DesignMode) conditional statement to be if (IsSerializing).