]>
git.saurik.com Git - wxWidgets.git/blob - docs/doxygen/overviews/propgrid.h
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: topic overview
4 // Author: wxWidgets team
6 // Licence: wxWindows license
7 /////////////////////////////////////////////////////////////////////////////
11 @page overview_propgrid wxPropertyGrid Overview
16 @li wxPropertyGridEvent
17 @li wxPropertyGridManager
18 @li wxPropertyGridPage
20 wxPropertyGrid is a specialized grid for editing properties such as strings,
21 numbers, flagsets, fonts, and colours. It is possible, for example, to categorize
22 properties, set up a complete tree-hierarchy, add multiple columns, and set
23 arbitrary per-property attributes.
25 @li @ref propgrid_basics
26 @li @ref propgrid_categories
27 @li @ref propgrid_parentprops
28 @li @ref propgrid_enumandflags
29 @li @ref propgrid_advprops
30 @li @ref propgrid_iterating
31 @li @ref propgrid_operations
32 @li @ref propgrid_events
33 @li @ref propgrid_validating
34 @li @ref propgrid_populating
35 @li @ref propgrid_cellrender
36 @li @ref propgrid_customizing
37 @li @ref propgrid_usage2
38 @li @ref propgrid_subclassing
39 @li @ref propgrid_misc
40 @li @ref propgrid_proplist
41 @li @ref propgrid_userhelp
42 @li @ref propgrid_notes
43 @li @ref propgrid_newprops
44 @li @ref propgrid_neweditors
46 @section propgrid_basics Creating and Populating wxPropertyGrid
48 As seen here, wxPropertyGrid is constructed in the same way as
49 other wxWidgets controls:
53 // Necessary header file
54 #include <wx/propgrid/propgrid.h>
58 // Assumes code is in frame/dialog constructor
60 // Construct wxPropertyGrid control
61 wxPropertyGrid* pg = new wxPropertyGrid(
64 wxDefaultPosition, // position
65 wxDefaultSize, // size
66 // Here are just some of the supported window styles
67 wxPG_AUTO_SORT | // Automatic sorting after items added
68 wxPG_SPLITTER_AUTO_CENTER | // Automatically center splitter until user manually adjusts it
72 // Window style flags are at premium, so some less often needed ones are
73 // available as extra window styles (wxPG_EX_xxx) which must be set using
74 // SetExtraStyle member function. wxPG_EX_HELP_AS_TOOLTIPS, for instance,
75 // allows displaying help strings as tooltips.
76 pg->SetExtraStyle( wxPG_EX_HELP_AS_TOOLTIPS );
80 (for complete list of new window styles, see @ref propgrid_window_styles)
82 wxPropertyGrid is usually populated with lines like this:
85 pg->Append( new wxStringProperty(wxT("Label"),wxT("Name"),wxT("Initial Value")) );
88 Naturally, wxStringProperty is a property class. Only the first function argument (label)
89 is mandatory. Second one, name, defaults to label and, third, the initial value, to
90 default value. If constant wxPG_LABEL is used as the name argument, then the label is
91 automatically used as a name as well (this is more efficient than manually defining both
92 as the same). Use of empty name is discouraged and will sometimes result in run-time error.
93 Note that all property class constructors have quite similar constructor argument list.
95 To demonstrate other common property classes, here's another code snippet:
100 pg->Append( new wxIntProperty(wxT("IntProperty"), wxPG_LABEL, 12345678) );
102 // Add float property (value type is actually double)
103 pg->Append( new wxFloatProperty(wxT("FloatProperty"), wxPG_LABEL, 12345.678) );
105 // Add a bool property
106 pg->Append( new wxBoolProperty(wxT("BoolProperty"), wxPG_LABEL, false) );
108 // A string property that can be edited in a separate editor dialog.
109 pg->Append( new wxLongStringProperty(wxT("LongStringProperty"),
111 wxT("This is much longer string than the ")
112 wxT("first one. Edit it by clicking the button.")));
114 // String editor with dir selector button.
115 pg->Append( new wxDirProperty(wxT("DirProperty"), wxPG_LABEL, ::wxGetUserHome()) );
117 // wxArrayStringProperty embeds a wxArrayString.
118 pg->Append( new wxArrayStringProperty(wxT("Label of ArrayStringProperty"),
119 wxT("NameOfArrayStringProp")));
121 // A file selector property.
122 pg->Append( new wxFileProperty(wxT("FileProperty"), wxPG_LABEL, wxEmptyString) );
124 // Extra: set wildcard for file property (format same as in wxFileDialog).
125 pg->SetPropertyAttribute( wxT("FileProperty"),
127 wxT("All files (*.*)|*.*") );
131 Operations on properties should be done either via wxPropertyGrid's
132 (or wxPropertyGridManager's) methods, or by acquiring pointer to a property
133 (Append returns a wxPGProperty* or wxPGId, which is typedef for same), and then
134 calling its method. Note however that property's methods generally do not
135 automatically update grid graphics.
137 Property container functions operating on properties, such as SetPropertyValue or
138 DisableProperty, all accept a special wxPGPropArg, argument which can automatically
139 convert name of a property to a pointer. For instance:
142 // A file selector property.
143 wxPGPropety* p = pg->Append( new wxFileProperty(wxT("FileProperty"), wxPG_LABEL, wxEmptyString) );
145 // Valid: Set wildcard by name
146 pg->SetPropertyAttribute( wxT("FileProperty"),
148 wxT("All files (*.*)|*.*") );
150 // Also Valid: Set wildcard by ptr
151 pg->SetPropertyAttribute( p,
153 wxT("All files (*.*)|*.*") );
156 Using pointer is faster, since it doesn't require hash map lookup. Anyway, you can allways
157 get property pointer (wxPGProperty*) as Append/Insert return value, or by calling
160 Below are samples for using some of the more commong operations. See
161 wxPropertyGridInterface and wxPropertyGrid class references for complete list.
165 // wxPGId is a short-hand for wxPGProperty*. Let's use it this time.
166 wxPGId id = pg->GetPropertyByName( wxT("MyProperty") );
168 // There are many overloaded versions of this method, of which each accept
169 // different type of value.
170 pg->SetPropertyValue( wxT("MyProperty"), 200 );
172 // Setting a string works for all properties - conversion is done
174 pg->SetPropertyValue( id, wxT("400") );
176 // Getting property value as wxVariant.
177 wxVariant value = pg->GetPropertyValue( wxT("MyProperty") );
179 // Getting property value as String (again, works for all typs).
180 wxString value = pg->GetPropertyValueAsString( id );
182 // Getting property value as int. Provokes a run-time error
183 // if used with property which value type is not "long".
184 long value = pg->GetPropertyValueAsLong( wxT("MyProperty") );
187 pg->SetPropertyName( wxT("MyProperty"), wxT("X") );
189 // Set new label - we need to use the new name.
190 pg->SetPropertyLabel( wxT("X"), wxT("New Label") );
192 // Disable the property. It's text will appear greyed.
193 // This is probably the closest you can get if you want
194 // a "read-only" property.
195 pg->DisableProperty( id );
200 @section propgrid_categories Categories
202 wxPropertyGrid has a hierarchial property storage and display model, which
203 allows property categories to hold child properties and even other
204 categories. Other than that, from the programmer's point of view, categories
205 can be treated exactly the same as "other" properties. For example, despite
206 its name, GetPropertyByName also returns a category by name, and SetPropertyLabel
207 also sets label of a category. Note however that sometimes the label of a
208 property category may be referred as caption (for example, there is
209 SetCaptionForegroundColour method that sets text colour of a property category's label).
211 When category is added at the top (i.e. root) level of the hierarchy,
212 it becomes a *current category*. This means that all other (non-category)
213 properties after it are automatically added to it. You may add
214 properties to specific categories by using wxPropertyGrid::Insert or wxPropertyGrid::AppendIn.
216 Category code sample:
220 // One way to add category (similar to how other properties are added)
221 pg->Append( new wxPropertyCategory(wxT("Main")) );
223 // All these are added to "Main" category
224 pg->Append( new wxStringProperty(wxT("Name")) );
225 pg->Append( new wxIntProperty(wxT("Age"),wxPG_LABEL,25) );
226 pg->Append( new wxIntProperty(wxT("Height"),wxPG_LABEL,180) );
227 pg->Append( new wxIntProperty(wxT("Weight")) );
230 pg->Append( new wxPropertyCategory(wxT("Attrikbutes")) );
232 // All these are added to "Attributes" category
233 pg->Append( new wxIntProperty(wxT("Intelligence")) );
234 pg->Append( new wxIntProperty(wxT("Agility")) );
235 pg->Append( new wxIntProperty(wxT("Strength")) );
240 @section propgrid_parentprops Tree-like Property Structure
242 As a new feature in version 1.3.1, basicly any property can have children. There
243 are few limitations, however.
246 - Names of properties with non-category, non-root parents are not stored in hash map.
247 Instead, they can be accessed with strings like "Parent.Child". For instance, in
248 the sample below, child property named "Max. Speed (mph)" can be accessed by global
249 name "Car.Speeds.Max Speed (mph)".
250 - If you want to property's value to be a string composed based on the values of
251 child properties, you must use wxStringProperty as parent and use value "<composed>".
252 - Events (eg. change of value) that occur in parent do not propagate to children. Events
253 that occur in children will propagate to parents, but only if they are wxStringProperties
254 with "<composed>" value.
255 - Old wxParentProperty class is deprecated, and remains as a typedef of wxStringProperty.
256 If you want old value behavior, you must specify "<composed>" as wxStringProperty's
262 wxPGId pid = pg->Append( new wxStringProperty(wxT("Car"),wxPG_LABEL,wxT("<composed>")) );
264 pg->AppendIn( pid, new wxStringProperty(wxT("Model"),
266 wxT("Lamborghini Diablo SV")) );
268 pg->AppendIn( pid, new wxIntProperty(wxT("Engine Size (cc)"),
272 wxPGId speedId = pg->AppendIn( pid, new wxStringProperty(wxT("Speeds"),wxPG_LABEL,wxT("<composed>")) );
273 pg->AppendIn( speedId, new wxIntProperty(wxT("Max. Speed (mph)"),wxPG_LABEL,290) );
274 pg->AppendIn( speedId, new wxFloatProperty(wxT("0-100 mph (sec)"),wxPG_LABEL,3.9) );
275 pg->AppendIn( speedId, new wxFloatProperty(wxT("1/4 mile (sec)"),wxPG_LABEL,8.6) );
277 // Make sure the child properties can be accessed correctly
278 pg->SetPropertyValue( wxT("Car.Speeds.Max. Speed (mph)"), 300 );
280 pg->AppendIn( pid, new wxIntProperty(wxT("Price ($)"),
283 // Displayed value of "Car" property is now:
284 // "Lamborghini Diablo SV; [300; 3.9; 8.6]; 300000"
288 @section propgrid_enumandflags wxEnumProperty and wxFlagsProperty
290 wxEnumProperty is used when you want property's (integer or string) value
291 to be selected from a popup list of choices.
293 Creating wxEnumProperty is more complex than those described earlier.
294 You have to provide list of constant labels, and optionally relevant values
295 (if label indexes are not sufficient).
299 - Value wxPG_INVALID_VALUE (equals INT_MAX) is not allowed as list
302 A very simple example:
307 // Using wxArrayString
309 wxArrayString arrDiet;
310 arr.Add(wxT("Herbivore"));
311 arr.Add(wxT("Carnivore"));
312 arr.Add(wxT("Omnivore"));
314 pg->Append( new wxEnumProperty(wxT("Diet"),
321 // Using wxChar* array
323 const wxChar* arrayDiet[] =
324 { wxT("Herbivore"), wxT("Carnivore"), wxT("Omnivore"), NULL };
326 pg->Append( new wxEnumProperty(wxT("Diet"),
333 Here's extended example using values as well:
338 // Using wxArrayString and wxArrayInt
340 wxArrayString arrDiet;
341 arr.Add(wxT("Herbivore"));
342 arr.Add(wxT("Carnivore"));
343 arr.Add(wxT("Omnivore"));
350 // Note that the initial value (the last argument) is the actual value,
351 // not index or anything like that. Thus, our value selects "Omnivore".
352 pg->Append( new wxEnumProperty(wxT("Diet"),
360 // Using wxChar* and long arrays
362 const wxChar* array_diet[] =
363 { wxT("Herbivore"), wxT("Carnivore"), wxT("Omnivore"), NULL };
365 long array_diet_ids[] =
368 pg->Append( new wxEnumProperty(wxT("Diet"),
375 wxPGChoices is a class where wxEnumProperty, and other properties which
376 require label storage, actually stores strings and values. It is used
377 to facilitiate reference counting, and therefore recommended way of
378 adding items when multiple properties share the same set.
380 You can use wxPGChoices directly as well, filling it and then passing it
381 to the constructor. Infact, if you wish to display bitmaps next to labels,
382 your best choice is to use this approach.
387 chs.Add(wxT("Herbivore"),40);
388 chs.Add(wxT("Carnivore"),45);
389 chs.Add(wxT("Omnivore"),50);
391 // Let's add an item with bitmap, too
392 chs.Add(wxT("None of the above"), wxBitmap(), 60);
394 // Note: you can add even whole arrays to wxPGChoices
396 pg->Append( new wxEnumProperty(wxT("Primary Diet"),
400 // Add same choices to another property as well - this is efficient due
401 // to reference counting
402 pg->Append( new wxEnumProperty(wxT("Secondary Diet"),
408 You can later change choices of property by using wxPGProperty::InsertChoice(),
409 wxPGProperty::DeleteChoice(), and wxPGProperty::SetChoices().
411 <b>wxEditEnumProperty</b> is works exactly like wxEnumProperty, except
412 is uses non-readonly combobox as default editor, and value is stored as
413 string when it is not any of the choices.
415 wxFlagsProperty has similar construction:
419 const wxChar* flags_prop_labels[] = { wxT("wxICONIZE"),
420 wxT("wxCAPTION"), wxT("wxMINIMIZE_BOX"), wxT("wxMAXIMIZE_BOX"), NULL };
422 // this value array would be optional if values matched string indexes
423 long flags_prop_values[] = { wxICONIZE, wxCAPTION, wxMINIMIZE_BOX,
426 pg->Append( new wxFlagsProperty(wxT("Window Style"),
430 wxDEFAULT_FRAME_STYLE) );
434 wxFlagsProperty can use wxPGChoices just the same way as wxEnumProperty
435 (and also custom property classes can be created with similar macro pairs).
436 <b>Note: </b> When changing "choices" (ie. flag labels) of wxFlagsProperty,
437 you will need to use wxPGProperty::SetChoices() to replace all choices
438 at once - otherwise they will not get updated properly.
440 @section propgrid_advprops Specialized Properties
442 This section describes the use of less often needed property classes.
443 To use them, you have to include <wx/propgrid/advprops.h>.
447 // Necessary extra header file
448 #include <wx/propgrid/advprops.h>
453 pg->Append( new wxDateProperty(wxT("MyDateProperty"),
455 wxDateTime::Now()) );
457 // Image file property. Wildcard is auto-generated from available
458 // image handlers, so it is not set this time.
459 pg->Append( new wxImageFileProperty(wxT("Label of ImageFileProperty"),
460 wxT("NameOfImageFileProp")) );
462 // Font property has sub-properties. Note that we give window's font as
464 pg->Append( new wxFontProperty(wxT("Font"),
468 // Colour property with arbitrary colour.
469 pg->Append( new wxColourProperty(wxT("My Colour 1"),
471 wxColour(242,109,0) ) );
473 // System colour property.
474 pg->Append( new wxSystemColourProperty(wxT("My SysColour 1"),
476 wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)) );
478 // System colour property with custom colour.
479 pg->Append( new wxSystemColourProperty(wxT("My SysColour 2"),
481 wxColour(0,200,160) ) );
484 pg->Append( new wxCursorProperty(wxT("My Cursor"),
491 @section propgrid_iterating Iterating through a property container
493 You can use somewhat STL'ish iterator classes to iterate through the grid.
494 Here is a simple example of forward iterating through all individual
495 properties (not categories or sub-propeties that are normally 'transparent'
496 to application code):
500 wxPropertyGridIterator it;
502 for ( it = pg->GetIterator();
506 wxPGProperty* p = *it;
507 // Do something with the property
512 As expected there is also a const iterator:
516 wxPropertyGridConstIterator it;
518 for ( it = pg->GetIterator();
522 const wxPGProperty* p = *it;
523 // Do something with the property
528 You can give some arguments to GetIterator to determine which properties
529 get automatically filtered out. For complete list of options, see
530 @ref propgrid_iterator_flags. GetIterator() also accepts other arguments.
531 See wxPropertyGridInterface::GetIterator() for details.
533 This example reverse-iterates through all visible items:
537 wxPropertyGridIterator it;
539 for ( it = pg->GetIterator(wxPG_ITERATE_VISIBLE, wxBOTTOM);
543 wxPGProperty* p = *it;
544 // Do something with the property
549 <b>wxPython Note:</b> Instead of ++ operator, use Next() method, and instead of
550 * operator, use GetProperty() method.
552 GetIterator() only works with wxPropertyGrid and the individual pages
553 of wxPropertyGridManager. In order to iterate through an arbitrary
554 property container, you need to use wxPropertyGridInterface::GetVIterator().
555 Note however that this virtual iterater is limited to forward iteration.
561 for ( it = manager->GetVIterator();
565 wxPGProperty* p = it.GetProperty();
566 // Do something with the property
572 @section propgrid_operations More About Operating with Properties
574 Getting value of selected wxSystemColourProperty (which value type is derived
579 wxPGId id = pg->GetSelection();
583 // Get name of property
584 const wxString& name = pg->GetPropertyName( id );
586 // If type is not correct, GetColour() method will produce run-time error
587 if ( pg->GetPropertyValueType() == wxT("wxColourPropertyValue") ) )
589 wxColourPropertyValue* pcolval =
590 wxDynamicCast(pg->GetPropertyValueAsWxObjectPtr(id),
591 wxColourPropertyValue);
595 if ( pcolval->m_type == wxPG_CUSTOM_COLOUR )
596 text.Printf( wxT("It is custom colour: (%i,%i,%i)"),
597 (int)pcolval->m_colour.Red(),
598 (int)pcolval->m_colour.Green(),
599 (int)pcolval->m_colour.Blue());
601 text.Printf( wxT("It is wx system colour (number=%i): (%i,%i,%i)"),
602 (int)pcolval->m_type,
603 (int)pcolval->m_colour.Red(),
604 (int)pcolval->m_colour.Green(),
605 (int)pcolval->m_colour.Blue());
607 wxMessageBox( text );
613 @section propgrid_populating Populating wxPropertyGrid Automatically
615 @subsection propgrid_fromvariants Populating from List of wxVariants
617 Example of populating an empty wxPropertyGrid from a values stored
618 in an arbitrary list of wxVariants.
622 // This is a static method that initializes *all* builtin type handlers
623 // available, including those for wxColour and wxFont. Refers to *all*
624 // included properties, so when compiling with static library, this
625 // method may increase the executable size significantly.
626 pg->InitAllTypeHandlers();
628 // Get contents of the grid as a wxVariant list
629 wxVariant all_values = pg->GetPropertyValues();
631 // Populate the list with values. If a property with appropriate
632 // name is not found, it is created according to the type of variant.
633 pg->SetPropertyValues( my_list_variant );
635 // In order to get wxObject ptr from a variant value,
636 // wxGetVariantCast(VARIANT,CLASSNAME) macro has to be called.
638 wxVariant v_txcol = pg->GetPropertyValue(wxT("Text Colour"));
639 const wxColour& txcol = wxGetVariantCast(v_txcol,wxColour);
643 @subsection propgrid_fromfile Loading Population from a Text-based Storage
645 Class wxPropertyGridPopulator may be helpful when writing code that
646 loads properties from a text-source. In fact, the supplied xrc handler
647 (src/xh_propgrid.cpp) uses it. See that code for more info.
648 NOTE: src/xh_propgrid.cpp is not included in the library by default,
649 to avoid dependency to wxXRC. You will need to add it to your application
652 @subsection propgrid_editablestate Saving and Restoring User-Editable State
654 You can use wxPGEditableState and wxPGMEditableState classes, and
655 wxPropertyGrid::SaveEditableState() and wxPropertyGrid::RestoreEditableState()
656 to save and restore user-editable state (selected property, expanded/
657 collapsed properties, and scrolled position). For convience with
658 program configuration, wxPGEditableState has functions to save/load
659 its value in wxString. For instance:
662 // Save state into config
663 wxPGEditableState edState;
664 pg->SaveEditableState(&edState);
665 programConfig->Store(wxT("PropertyGridState"), edState.GetAsString());
667 // Restore state from config
668 wxPGEditableState edState;
669 edState.SetFromString(programConfig->Load(wxT("PropertyGridState")));
670 pg->RestoreEditableState(edState);
674 @section propgrid_events Event Handling
676 Probably the most important event is the Changed event which occurs when
677 value of any property is changed by the user. Use EVT_PG_CHANGED(id,func)
678 in your event table to use it.
680 For complete list of event types, see wxPropertyGrid class reference.
682 The custom event class, wxPropertyGridEvent, has methods to directly
683 access the property that triggered the event.
685 Here's a small sample:
689 // Portion of an imaginary event table
690 BEGIN_EVENT_TABLE(MyForm, wxFrame)
694 // This occurs when a property value changes
695 EVT_PG_CHANGED( PGID, MyForm::OnPropertyGridChange )
701 void MyForm::OnPropertyGridChange( wxPropertyGridEvent& event )
703 wxPGProperty *property = event.GetProperty();
709 // Get name of changed property
710 const wxString& name = property->GetName();
712 // Get resulting value
713 wxVariant value = property->GetValue();
718 Another event type you might find useful is EVT_PG_CHANGING, which occurs
719 just prior property value is being changed by user. You can acquire pending
720 value using wxPropertyGridEvent::GetValue(), and if it is not acceptable,
721 call wxPropertyGridEvent::Veto() to prevent the value change from taking
726 // Portion of an imaginary event table
727 BEGIN_EVENT_TABLE(MyForm, wxFrame)
731 // This occurs when a property value changes
732 EVT_PG_CHANGING( PGID, MyForm::OnPropertyGridChanging )
738 void MyForm::OnPropertyGridChanging( wxPropertyGridEvent& event )
740 wxPGProperty* property = event.GetProperty();
742 if ( property == m_pWatchThisProperty )
744 // GetValue() returns the pending value, but is only
745 // supported by wxEVT_PG_CHANGING.
746 if ( event.GetValue().GetString() == g_pThisTextIsNotAllowed )
756 @remarks On Sub-property Event Handling
757 - For aggregate type properties (wxFontProperty, wxFlagsProperty, etc), events
758 occur for the main parent property only. For other properties events occur
759 for the children themselves..
761 - When property's child gets changed, you can use wxPropertyGridEvent::GetMainParent
762 to obtain its topmost non-category parent (useful, if you have deeply nested
766 @section propgrid_validating Validating Property Values
768 There are various ways to make sure user enters only correct values. First, you
769 can use wxValidators similar to as you would with ordinary controls. Use
770 wxPropertyGridInterface::SetPropertyValidator() to assign wxValidator to
773 Second, you can subclass a property and override wxPGProperty::ValidateValue(),
774 or handle wxEVT_PG_CHANGING for the same effect. Both of these methods do not
775 actually prevent user from temporarily entering invalid text, but they do give
776 you an opportunity to warn the user and block changed value from being committed
779 Various validation failure options can be controlled globally with
780 wxPropertyGrid::SetValidationFailureBehavior(), or on an event basis by
781 calling wxEvent::SetValidationFailureBehavior(). Here's a code snippet of
782 how to handle wxEVT_PG_CHANGING, and to set custom failure behaviour and
786 void MyFrame::OnPropertyGridChanging(wxPropertyGridEvent& event)
788 wxPGProperty* property = event.GetProperty();
790 // You must use wxPropertyGridEvent::GetValue() to access
791 // the value to be validated.
792 wxVariant pendingValue = event.GetValue();
794 if ( property->GetName() == wxT("Font") )
796 // Make sure value is not unspecified
797 if ( !pendingValue.IsNull() )
799 wxFont font << pendingValue;
801 // Let's just allow Arial font
802 if ( font.GetFaceName() != wxT("Arial") )
805 event.SetValidationFailureBehavior(wxPG_VFB_STAY_IN_PROPERTY |
807 wxPG_VFB_SHOW_MESSAGE);
815 @section propgrid_cellrender Customizing Individual Cell Appearance
817 You can control text colour, background colour, and attached image of
818 each cell in the property grid. Use wxPropertyGridInterface::SetPropertyCell() or
819 wxPGProperty::SetCell() for this purpose.
821 In addition, it is possible to control these characteristics for
822 wxPGChoices list items. See wxPGChoices class
823 reference for more info.
826 @section propgrid_customizing Customizing Properties (without sub-classing)
828 In this section are presented miscellaneous ways to have custom appearance
829 and behavior for your properties without all the necessary hassle
830 of sub-classing a property class etc.
832 @subsection propgrid_customimage Setting Value Image
834 Every property can have a small value image placed in front of the
835 actual value text. Built-in example of this can be seen with
836 wxColourProperty and wxImageFileProperty, but for others it can
837 be set using wxPropertyGrid::SetPropertyImage method.
839 @subsection propgrid_customvalidator Setting Validator
841 You can set wxValidator for a property using wxPropertyGrid::SetPropertyValidator.
843 Validator will work just like in wxWidgets (ie. editorControl->SetValidator(validator)
846 @subsection propgrid_customeditor Setting Property's Editor Control(s)
848 You can set editor control (or controls, in case of a control and button),
849 of any property using wxPropertyGrid::SetPropertyEditor. Editors are passed
850 using wxPG_EDITOR(EditorName) macro, and valid built-in EditorNames are
851 TextCtrl, Choice, ComboBox, CheckBox, TextCtrlAndButton, ChoiceAndButton,
852 SpinCtrl, and DatePickerCtrl. Two last mentioned ones require call to
853 static member function wxPropertyGrid::RegisterAdditionalEditors().
855 Following example changes wxColourProperty's editor from default Choice
856 to TextCtrlAndButton. wxColourProperty has its internal event handling set
857 up so that button click events of the button will be used to trigger
858 colour selection dialog.
862 wxPGId colProp = pg->Append(wxColourProperty(wxT("Text Colour")));
864 pg->SetPropertyEditor(colProp,wxPG_EDITOR(TextCtrlAndButton));
868 Naturally, creating and setting custom editor classes is a possibility as
869 well. For more information, see wxPGEditor class reference.
871 @subsection propgrid_editorattrs Property Attributes Recognized by Editors
873 <b>SpinCtrl</b> editor can make use of property's "Min", "Max", "Step" and "Wrap" attributes.
875 @subsection propgrid_multiplebuttons Adding Multiple Buttons Next to an Editor
877 See wxPGMultiButton class reference.
879 @subsection propgrid_customeventhandling Handling Events Passed from Properties
881 <b>wxEVT_COMMAND_BUTTON_CLICKED </b>(corresponds to event table macro EVT_BUTTON):
882 Occurs when editor button click is not handled by the property itself
883 (as is the case, for example, if you set property's editor to TextCtrlAndButton
884 from the original TextCtrl).
886 @subsection propgrid_attributes Property Attributes
888 Miscellaneous values, often specific to a property type, can be set
889 using wxPropertyGrid::SetPropertyAttribute and wxPropertyGrid::SetPropertyAttributeAll
892 Attribute names are strings and values wxVariant. Arbitrary names are allowed
893 inorder to store user values. Constant equivalents of all attribute string names are
894 provided. Some of them are defined as cached strings, so using constants can provide
895 for smaller binary size.
897 For complete list of attributes, see @ref propgrid_property_attributes.
899 @subsection propgrid_boolcheckbox Setting wxBoolProperties to Use Check Box
901 To have all wxBoolProperties to use CheckBox editor instead of Choice, use
902 following (call after bool properties have been added):
905 pg->SetPropertyAttributeAll(wxPG_BOOL_USE_CHECKBOX,true);
909 @section propgrid_usage2 Using wxPropertyGridManager
911 wxPropertyGridManager is an efficient multi-page version of wxPropertyGrid,
912 which can optionally have toolbar for mode and page selection, and a help text
915 wxPropertyGridManager inherits from wxPropertyGridInterface, and as such
916 it has most property manipulation functions. However, only some of them affect
917 properties on all pages (eg. GetPropertyByName() and ExpandAll()), while some
918 (eg. Append()) only apply to the currently selected page.
920 To operate explicitly on properties on specific page, use wxPropertyGridManager::GetPage()
921 to obtain pointer to page's wxPropertyGridPage object.
923 Visual methods, such as SetCellBackgroundColour and GetNextVisible are only
924 available in wxPropertyGrid. Use wxPropertyGridManager::GetGrid() to obtain
927 Iteration methods will not work in wxPropertyGridManager. Instead, you must acquire
928 the internal grid (GetGrid()) or wxPropertyGridPage object (GetPage()).
930 wxPropertyGridManager constructor has exact same format as wxPropertyGrid
931 constructor, and basicly accepts same extra window style flags (albeit also
932 has some extra ones).
934 Here's some example code for creating and populating a wxPropertyGridManager:
938 wxPropertyGridManager* pgMan = new wxPropertyGridManager(this, PGID,
939 wxDefaultPosition, wxDefaultSize,
940 // These and other similar styles are automatically
941 // passed to the embedded wxPropertyGrid.
942 wxPG_BOLD_MODIFIED|wxPG_SPLITTER_AUTO_CENTER|
945 // Include description box.
947 // Include compactor.
950 wxPGMAN_DEFAULT_STYLE
953 wxPropertyGridPage* page;
955 // Adding a page sets target page to the one added, so
956 // we don't have to call SetTargetPage if we are filling
957 // it right after adding.
958 pgMan->AddPage(wxT("First Page"));
959 page = pgMan->GetLastPage();
961 page->Append( new wxPropertyCategory(wxT("Category A1")) );
963 page->Append( new wxIntProperty(wxT("Number"),wxPG_LABEL,1) );
965 page->Append( new wxColourProperty(wxT("Colour"),wxPG_LABEL,*wxWHITE) );
967 pgMan->AddPage(wxT("Second Page"));
968 page = pgMan->GetLastPage();
970 page->Append( wxT("Text"),wxPG_LABEL,wxT("(no text)") );
972 page->Append( new wxFontProperty(wxT("Font"),wxPG_LABEL) );
976 @subsection propgrid_propgridpage wxPropertyGridPage
978 wxPropertyGridPage is holder of properties for one page in manager. It is derived from
979 wxEvtHandler, so you can subclass it to process page-specific property grid events. Hand
980 over your page instance in wxPropertyGridManager::AddPage.
982 Please note that the wxPropertyGridPage itself only sports subset of wxPropertyGrid API
983 (but unlike manager, this include item iteration). Naturally it inherits from
984 wxPropertyGridMethods and wxPropertyGridPageState.
987 @section propgrid_subclassing Subclassing wxPropertyGrid and wxPropertyGridManager
991 - Only a small percentage of member functions are virtual. If you need more,
992 just e-mail to wx-dev mailing list.
994 - Data manipulation is done in wxPropertyGridPageState class. So, instead of
995 overriding wxPropertyGrid::Insert, you'll probably want to override wxPropertyGridPageState::DoInsert.
997 - Override wxPropertyGrid::CreateState to instantiate your derivate wxPropertyGridPageState.
998 For wxPropertyGridManager, you'll need to subclass wxPropertyGridPage instead (since it
999 is derived from wxPropertyGridPageState), and hand over instances in wxPropertyGridManager::AddPage
1002 - You can use a derivate wxPropertyGrid with manager by overriding wxPropertyGridManager::CreatePropertyGrid
1006 @section propgrid_misc Miscellaneous Topics
1008 @subsection propgrid_namescope Property Name Scope
1010 All properties which parent is category or root can be accessed
1011 directly by their base name (ie. name given for property in its constructor).
1012 Other properties can be accessed via "ParentsName.BaseName" notation,
1013 Naturally, all property names should be unique.
1015 @subsection propgrid_nonuniquelabels Non-unique Labels
1017 It is possible to have properties with identical label under same parent.
1018 However, care must be taken to ensure that each property still has
1021 @subsection propgrid_boolproperty wxBoolProperty
1023 There are few points about wxBoolProperty that require futher discussion:
1024 - wxBoolProperty can be shown as either normal combobox or as a checkbox.
1025 Property attribute wxPG_BOOL_USE_CHECKBOX is used to change this.
1026 For example, if you have a wxFlagsProperty, you can
1027 set its all items to use check box using the following:
1029 pg->SetPropertyAttribute(wxT("MyFlagsProperty"),wxPG_BOOL_USE_CHECKBOX,true,wxPG_RECURSE);
1032 - Default item names for wxBoolProperty are ["False", "True"]. This can be
1033 changed using wxPropertyGrid::SetBoolChoices(trueChoice, falseChoice).
1035 @subsection propgrid_textctrlupdates Updates from wxTextCtrl Based Editor
1037 Changes from wxTextCtrl based property editors are committed (ie.
1038 wxEVT_PG_CHANGED is sent etc.) *only* when (1) user presser enter, (2)
1039 user moves to edit another property, or (3) when focus leaves
1042 Because of this, you may find it useful, in some apps, to call
1043 wxPropertyGrid::CommitChangesFromEditor() just before you need to do any
1044 computations based on property grid values. Note that CommitChangesFromEditor()
1045 will dispatch wxEVT_PG_CHANGED with ProcessEvent, so any of your event handlers
1046 will be called immediately.
1048 @subsection propgrid_splittercentering Centering the Splitter
1050 If you need to center the splitter, but only once when the program starts,
1051 then do <b>not</b> use the wxPG_SPLITTER_AUTO_CENTER window style, but the
1052 wxPropertyGrid::CenterSplitter() method. <b>However, be sure to call it after
1053 the sizer setup and SetSize calls!</b> (ie. usually at the end of the
1054 frame/dialog constructor)
1056 @subsection propgrid_splittersetting Setting Splitter Position When Creating Property Grid
1058 Splitter position cannot exceed grid size, and therefore setting it during
1059 form creation may fail as initial grid size is often smaller than desired
1060 splitter position, especially when sizers are being used.
1062 @subsection propgrid_colourproperty wxColourProperty and wxSystemColourProperty
1064 Through subclassing, these two property classes provide substantial customization
1065 features. Subclass wxSystemColourProperty if you want to use wxColourPropertyValue
1066 (which features colour type in addition to wxColour), and wxColourProperty if plain
1069 Override wxSystemColourProperty::ColourToString() to redefine how colours are
1072 Override wxSystemColourProperty::GetCustomColourIndex() to redefine location of
1073 the item that triggers colour picker dialog (default is last).
1075 Override wxSystemColourProperty::GetColour() to determine which colour matches
1078 @section propgrid_proplist Property Class Descriptions
1080 See @ref pgproperty_properties