The PropertyGrid: Overriding Class Attributes
Dynamically control any attribute, including DefaultValues, Categories, Descriptions, DisplayNames, ReadOnly attributes, Property sort order and more.

Introduction
The DynamicPropWrapper
class wraps an existing class and filters the property information that the .NET PropertyGrid
displays. The purpose for this is mainly to control the ReadOnly
and DefaultValues
for each property dynamically in the code. Other features include dynamic modification of the Categories, Descriptions, DisplayNames, Property sorting order and more.
- Two methods for handling default values
- Wraps an existing class, making it a drop-in solution
- Overrides attributes with one line of code
- Preserves all existing attribute information that may already be defined in your class
- Add/override any attribute desired
Using the Code
To use the DynamicPropWrapper
class, do the following:
// This is the class object whose properties you want
// to see in the PropertyGrid.
mTestObject = new DemoClass1;
// The DynamicPropWrapper is the Main class used
// to filter property information from the class above.
mDynPropWrapper = new DynamicPropWrapper(mTestObject);
// The PropertyGrid.SelectedObject gets set to the
// DynamicPropWrapper.DynamicDescriptor property. This
// allows the DynamicPropWrapper class to describe the
// type information for mTestObject.
propertyGrid1.SelectedObject = mDynPropWrapper.DynamicDescriptor;
Overriding Attributes
Overriding a property attribute can be done with one line of code:
// Overriding/Adding a DefaultValue
mDynPropWrapper["MyPropertyName"].Overrides.Replace_
(new DefaultValueAttribute("New Default Value"));
// Overriding/Adding a ReadOnly
mDynPropWrapper["MyPropertyName"].Overrides.Replace_
(new ReadOnlyAttribute(true));
The DefaultValue
First, note the following: PRB: XML Serialization: System.Xml.XmlSerializer Does Not Serialize Default Values. Microsoft recognized this as a problem in .NET 1.1 and claimed it would be resolved in its next framework release. Apparently it never got done. The result is that any class property whose value matches the default value will not be serialized by the XmlSerializer
. This was no doubt done intentionally in an effort to reduce the size of the final output stream, but it also means that the class object it was serialized with is required to re-construct the data.
Using the DynamicPropWrapper
class, you can omit DefaultValueAttributes
from your classes and control the default value in two ways:
- By overriding the default values for each property - see the example above
- By using a global
DefaultValueObject
for all property default values - see the example below
// This is the class object whose properties you want
// to see in the PropertyGrid.
mTestObject = new DemoClass1;
// This is the class that represents the default values
// for mTestObject.
mTestObject_Defaults = new DemoClass1();
// The DynamicPropWrapper is the Main class used
// to filter property information from the class above.
mDynPropWrapper = new DynamicPropWrapper(mTestObject);
// Assign a global DefaultValueObject.
mDynPropWrapper.OverrideProps.DefaultValueObject = mTestObject_Defaults;
// The PropertyGrid.SelectedObject gets set to the
// DynamicPropWrapper.DynamicDescriptor property. This
// allows the DynamicPropWrapper class to describe the
// type information for mTestObject.
propertyGrid1.SelectedObject = mDynPropWrapper.DynamicDescriptor;
You can now use mTestObject_Defaults
to manage the default values for mTestObject
. The DynamicPropWrapper
class will first look for a global DefaultValueObject
. If one is not found, it looks in the attributes collection for a DefaultValueAttribute
. If a DefaultValue
override has been set, it will use this. If there is no DefaultValueObject
and no DefaultValue
override, it will use the "hard-coded" DefaultValueAttribute
in the class (if one exists).
Property Sorting
Properties can be ordered in two ways:
Natural
- Properties appear in the same order that they were defined in the codeUsePropertySortAttributes
- You can apply aSortPropsByAttribute
to each property. This class takes anInteger
as an argument for sorting
NOTE: The PropertyGrid
View ToolBar Buttons (Categorized
/Alphabetical
) will always set the PropertySort
to either CategorizedAlphabetical
or Alphabetical
. This overrides any sorting done with the property descriptors. To remedy this, add an event handler to the PropertySortChanged
event and force the PropertySort
to either Categorized
or None
.
DynamicPropWrapper Members
Namespace:DynamicProps
Wrap this class around your class object and point the PropertyGrid
SelectedObject
property to DynamicPropWrapper.DynamicDescriptor
for dynamic property control.
Constructors
DynamicPropWrapper()
- This constructor is only used ifDynamicPropWrapper
is inheritedDynamicPropWrapper(Object instance)
- Always use this constructor when wrapping a class
Parameter Name | Type | Description |
instance |
Object |
The object whose properties are to be filtered |
Methods
Object GetDefaultPropValue(String propName)
- Returns the default value via theDynamicTypeDescriptor
; this is the same value that thePropertyGrid
will see when it asks for theDefaultValue
.Object GetPropValue(String propName)
- Returns the property value via theDynamicTypeDescriptor
; this is the same value that thePropertyGrid
will see when it asks for the property value.
Properties
Property Name | Type | Accessors | Description |
Item |
DynPropertyOverride |
Get /Set (default) |
Indexer for accessing the OverrideProps property |
DynamicDescriptor |
DynamicTypeDescriptor |
Get |
Returns the DynamicDescriptor object that is used by PropertyGrid |
Instance |
Object |
Get /Set |
An instance of the class whose properties you want to dynamically filter/modify |
OverrideProps |
DynPropertyOverrideList |
Get |
Dictionary list of the class properties that are being overridden. Each dictionary item contains a list of the attributes that are being overridden. Use this property (or the indexer) to view and manipulate the dynamic property information |
PropertySortType |
DynPropertySortTypes |
Get /Set |
Change the order in which properties are listed in the PropertyGrid |
Points of Interest
Although it was never intended, you can also inherit the DynamicPropWrapper
class and it automatically adjusts to provide type information for the object that inherited it. If you choose to use it this way, don't set the Instance
property. This will force it back to a non-inherited mode and it will consequently get stuck in an infinite loop. Here are some other articles at The Code Project that have similar functionality:
History
- 01-12-2008:
DynamicProps
1.2.0- Bug fixed: setting the
Instance
property forces the sort order to default
- Bug fixed: setting the
- 08-04-2007:
DynamicProps
1.1.0- Bug fixed:
DefaultValueObject
would not work unless at least one override attribute was set - Additional documentation added to demo source code
- Bug fixed:
- 07-30-2007:
DynamicProps
1.0.0 - Initial release