Introduction
This article
implements a fully customizable property
grid as can be seen in the above
screenshots. The grid
supports various types of items: strings,
combos, file pickers... It also supports fully customizable
items that can define how they are drawn, how
the user interacts with them and their behavior
when edited.
Background
As developers,
we are now all used to the Properties
Window of Visual
Studio and this article is an
implementation of this. It does not support the
help area and although the control supports
different types of display (categorized,
alphabetical...) standard buttons for this are
not provided.
Using the code
The sample
application provided shows almost all that can
be done with the control.
You are therefore encouraged to parse the source
code to learn about the control!
First we have
placed a dummy control
in our dialog (in our case a Picture Control)
and overridden the type of the control
in the header file to be a CPropertyGrid
.
In the OnInitDialog
of the dialog,
we initialize the controls
using various methods:
AddSection
:
used to add a group of properties
(see "Basic Items" of the
screenshot)
AddXXXItem
:
used to add items to a section (see below
for the various items types)
SetXXXStrings
:
used to localize the standard dialogs used
by the CPropertyGrid
(see below)
Basically, if
the only thing we want to do is to display
standard properties,
then we are done!
Standard item
types
As said
previously, the control supports different
items, so here is a quick description of those
types:
AddStringItem
:
a simple single line string item. The string
can be edited in-place
AddTextItem
:
a multiline string item. When edited, CPropertyGrid
dynamically generates a dialog allowing the
user to enter the text
AddIntegerItem
:
an integer value item. An optional
formatting mucancode.net can be provided
AddDoubleItem
:
a floating point value item. An optional
formatting mucancode.net can be provided
AddComboItem
:
an item allowing to choose among a set of
values. The possible values are passed as a vector<string>
AddBoolItem
:
a boolean value item which behaves like a
Combo Item. True
and False
texts can be set using SetTrueFalseStrings
AddDateItem
:
a date value item chosen using a CMonthCalCtrl
derived control.
AddDateTimeItem
:
a date and time value set using a
dynamically generated dialog
AddFileItem
:
an item allowing to choose a file using a
standard CFileDialog
. A filter
list can be provided
AddFolderItem
:
an item allowing to choose a folder using a
"standard" directory picker dialog
AddColorItem
:
an item allowing to choose a color using a
standard CColorDialog
AddFontItem
:
an item allowing to choose a color using a
standard CFontDialog
Custom items
CPropertyGrid
also supports full custom items. To implement a
custom item, simply create a new class and make
it derive from ICustomItem
and
implement the various methods of this interface.
Then create an instance of your class and add it
the grid control using
AddCustomItem
. Two methods of ICustomItem
are purely virtual and must be overridden:
GetEditMode
:
tells the grid
what kind of interaction your control
is using when editing the value. The sample
application shows four custom items that
implement the various edit modes.
DrawItem
:
override this to draw your custom item. This
can be as simple as calling DrawText
on the provided CDC
.
Next, depending
on the edit mode, you may override more methods
to customize your item. To better understand how
this works it is recommended to check the
various custom items implemented in the sample
application: CSerialItem
for
in-place editing, CRectItem
for
modal editing, CTreeItem
for
dropdown editing and CGradientItem
for a full custom item.
- In-place
edited items should override
GetStringForInPlaceEdit
(to tell the grid
the string that should be edited) and OnItemEdited
(return false
to discard the
edit)
- Dropdown
custom items should override
ShowDropDown
and show their dropdown control
here
- Modal custom
items should override
OnEditItem
and show their modal dialog here
- Custom edit
mode items should override
OnLButtonDown
,
OnMouseMove
and OnLButtonUp
to implement their mouse events specific
handling
Display customization
Rendering of
the grid can also be customized using various
methods:
- Title
shading: control
if you want to have a different background
color for section headers
- Draw lines:
control if you want to display horizontal grid
lines or not
- Gutter: control
if you want to display the vertical line
between property
names and values. You can also control
the width of the gutter
- Focus
disabled: control
if you want disabled items to be selectable
or not
- Colors: use
the various
SetXXXColor
methods
to change the colors used to draw the grid
Value editing
You can use the
GetItemValue
and SetItemValue
overloads to get the value of a specific item.
The HITEM
expected is one returned
when you called AddXXXItem
when
initializing your control.
Make sure you call the good overload when
calling this function: obviously you cannot get
double from date item and you cannot set a LOGFONT
in a text item. That's why all these functions
return a boolean value indicating if things went
well or not.
Points of
Interest
I must warn you
that this is some code that I wrote a while back
and that has not changed much since. I always
wanted to put this one on Codeproject
but obviously did not find time to do it. Now
it's done!
I only provided
project files for Visual Studio 2005 but I see
no reason as to why the code should not work
with 2003 or even 6.0. Maybe some minor
adjustments should be done but it should not be
a big issue.
I am using two
other articles available on codeproject.com:
- Dynamic
dialogs
CInPlaceEdit
from Chris' Grid
Control
Conclusion
This was a fun control
to write especially supporting full custom
items. My description of the control does not
cover all aspects of the control and I encourage
you to review its header file to discover things
that I have not taken the time to talk about.
Nevertheless, I hope that this short article let
you see all the possibilities of the control!