Hi Mary,
Technically the properties are shown in bold if the IPropertyDataAccessor.IsModified returns true. The default implementation calls the ShouldSerializeValue method of the associated PropertyDescriptor. There are a few concrete implementations of PropertyDescriptor, so each can be a bit different.
If you are dealing with CLR properties (i.e. not WPF dependency properties), then the PropertyDescriptor will check two things. First it compares the property's value with it's "default value" using the Object.Equals method. The default value comes from the DefaultAttribute. This is generally statically defined, but there are a few ways to make it dynamic.
Next it will look for a ShouldSerializeMyProperty method (assuming your property is named MyProperty) on your object. The name is a bit confusing, but this effecitvely says if MyProperty has changed (and thus needs to be saved). More information can be found
here.
So you could implement ShouldSerialize* for your properties. You'd need to save the "initial" value and only return true if it's changed. The problem with this approach is the ShouldSerialize methods also affect any .NET serializers (binary or XML) and embeds the view logic in the object.
The only other alternative would be to:
1. Create a custom DataFactory that derives from TypeDescriptorFactory (i.e. MyDataFactory).
2. Create a custom class that derives from PropertyDescriptorDataAccessor (i.e. MyPropertyDescriptorDataAccessor).
3. Create a constructor on MyPropertyDescriptorDataAccessor that matches the PropertyDescriptorDataAccessor main constructor. Such as:
public MyPropertyDescriptorDataAccessor(IPropertyDataAccessor parent, object target, PropertyDescriptor propertyDescriptor)
: base(parent, target, propertyDescriptor) {
// No-op
}
4. Override the MyDataFactory.CreatePropertyDataAccessor and return instances of your MyPropertyDescriptorDataAccessor and do not call teh base implementation.
5. In your MyPropertyDescriptorDataAccessor you'd want to add a Boolean field (i.e. isModified) and override the IsModifiedInternal property to return the value of that field.
6. Override the OnValueChanged method in your MyPropertyDescriptorDataAccessor and set your isModified field to true, then call the base implementation.
You may need to override the ValueInternal and ValueAsStringInternal properties instead, if OnValueChanged is called to often. Since OnValueChanged can be used to refresh the UI, even if the property's value has not changed. If you have to override the properties, then you'd need to set isModified in the setters, but otherwise call the base implementation.
7. Then you'd need to need set the PropertyGrid.DataFactory to an instance of your MyDataFactory.