PropertyGridEx






2.20/5 (6 votes)
Nov 16, 2006
4 min read

82425

1419
A control which extends the functionality of the PropertyGrid.
Introduction
In my last article, I described a control that extends the functionality of the System.Windows.Forms.PropertyGrid
. Now, let’s demonstrate the control. This diagram illustrates how the system property grid displays items:
Activity Diagram 1
PropertGrid
selects an object derived from theSystem.ComponentModel.ICustomTypeDescriptor
interface used by theSelectedObject
property.PropertGrid
invokes theICustomTypeDescriptor::GetProperties()
method and gets theSystem.ComponentModel.PropertyDescriptorCollection
object that contains the collection ofSystem.ComponentModel.PropertyDescriptor
objects.- Using the methods and properties of the
System.ComponentModel.PropertyDescriptor
object,PropertGrid
gets the description of each item (for example: display name, value, and others). - If an item contains sub-items, then the
PropertyDescriptor
object should return an appropriate object derived from theSystem.ComponentModel.ICustomTypeDescriptor
interface that describes a child item, through theGetValue()
method. If an item has a simple system type, then this method returns just one.
Examine how the Puma.Controls.PropertyGrid
provides the necessary data for the system property grid:
Here is a reference of the extended interfaces:
IPropertyGridItemEx is derived from IPropertyGridItem
Provides auxiliary information about the item, most essential being the appropriate PropertyDescriptor
object that is used by the property grid for displaying the item (see how the system property grid displays an item).
Has the following properties and methods:
Properties:
System.ComponentModel.PropertyDescriptor PropertyDescriptor {get;}
Returns the
PropertyDescriptor
object that describes the item.IPropertyGridItemsEx ChildsEx {get;}
Returns the
IPropertyGridItemsEx
interface for the item. If the interface has not yet been created, returnnull
.IPropertyGridItemRootEx RootItemEx {get;}
Returns the root item of the items tree.
IPropertyGridItem BaseItem {get;}
Returns the base
IPropertyGridItem
interface for this item.int Index {get;}
Returns the index of the element in the parent’s child fragment collection.
Remark:
This is the index relative to the first item in the fragment (see the
IPropertyGridChildItemsFragment
description), not to the child container (see theIPropertyGridChildItems
description).bool IsCategory {get;}
Returns a flag indicating whether the item represents a category item.
Remark:
IsCategory
returnstrue
if this item is a sub-root item. In this case, when the property grid is displayed in Category mode andPropertyGrid.FirstItemsAsCategories = true
, then the item is displayed as the category for all of its child items.
Methods:
IPropertyGridItemsEx CreateChildsEx()
Creates and returns the
IPropertyGridItemsEx
interface for the item.string OnValueValidate(string Value);
Validates the value changed by the user before it is recorded by the property grid. Accepts a new value from the user, validates it, reformats it if necessary, and returns.
IPropertyGridChildItemsEx derived from IPropertyGridChildItems
Properties:
System.ComponentModel.PropertyDesriptorCollection PropertyDesriptorCollection {get;}
Provides appropriately formatted information for the property grid about the child of the item.
Puma.Controls.PropertyGridEx
activity diagram:
Activity Diagram 2
Notice:
- When the diagram indicates what should be created for an interface, this means that a class is created that implements this interface (in the Puma.Control.PropertyGridEx project, these classes are
PropertyGridChildItemsExImpl
andPropertyGridItemExImpl
forIPropertyGridChildItemsEx
andIPropertyGridItemEx
, respectively).It is clear that not all sequenced activities that accomplish these interfaces are strictly defined. What is important for the robust functionality of this system is that all members of the base interface are implemented, in what manner does not matter.
PropertyGrid.GetProperties
returns a collection which contains aPropertyDescriptor
object whoseGetValue()
method returns aPropertyGridItem
object or simply a string value. If it returns aPropertyGridItem
object, execute all sequence of actions in the same order, beginning from thePropertyGrid.GetProperties
operation.When an item displayed by the property grid invokes its methods and properties of the appropriate
PropertyDescriptor
object (see Activity diagram 1), for the purpose of this project, all these invocations are delegated to thePropertyGridItemEx
object (see Activity diagram 2), since we want to change the default representation of an item in the property grid with the appropriate overridden methods and properties of thePropertyGridItemEx
object. This is why we need to derive a class from thePropertyGridItemEx
class and override the necessary properties.
Example:
public class NewPropertyGridItemExImpl :
Puma.Controls.PropertyGrid.PropertyGridItemExImpl
{
...
public override string Value
{
get
{
//All values in property grid are displayed with
//prefix [Changed value representation]
return “[Changed value representation]” + base.Value;
}
set
{
base.Value = value;
}
}
...
Now implement this class used by the property grid in the place of the base class. This should override the PropertyGridItemRootExImpl
, PropertyGridItemExImpl
, and PropertyGridChildItemsExImpl
classes.
Schematically:
To see how this class is implemented in the current project, see the PropertyGridItemExImpl.cs, PropertyGridItemRootExImpl.cs, and the PropertyGridChildItemsExImpl.cs files.
Thanks to Arnie Berg for his contribution in this article writing.