]>
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.
46 @section 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: @link wndflags Additional Window Styles@endlink)
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
92 defining both as the same). Empty name is also allowed, but in this case the
93 property cannot be accessed by its name. Note that all property class constructors have
94 quite similar constructor argument list.
96 To demonstrate other common property classes, here's another code snippet:
101 pg->Append( new wxIntProperty(wxT("IntProperty"), wxPG_LABEL, 12345678) );
103 // Add float property (value type is actually double)
104 pg->Append( new wxFloatProperty(wxT("FloatProperty"), wxPG_LABEL, 12345.678) );
106 // Add a bool property
107 pg->Append( new wxBoolProperty(wxT("BoolProperty"), wxPG_LABEL, false) );
109 // A string property that can be edited in a separate editor dialog.
110 pg->Append( new wxLongStringProperty(wxT("LongStringProperty"),
112 wxT("This is much longer string than the ")
113 wxT("first one. Edit it by clicking the button.")));
115 // String editor with dir selector button.
116 pg->Append( new wxDirProperty(wxT("DirProperty"), wxPG_LABEL, ::wxGetUserHome()) );
118 // wxArrayStringProperty embeds a wxArrayString.
119 pg->Append( new wxArrayStringProperty(wxT("Label of ArrayStringProperty"),
120 wxT("NameOfArrayStringProp")));
122 // A file selector property.
123 pg->Append( new wxFileProperty(wxT("FileProperty"), wxPG_LABEL, wxEmptyString) );
125 // Extra: set wildcard for file property (format same as in wxFileDialog).
126 pg->SetPropertyAttribute( wxT("FileProperty"),
128 wxT("All files (*.*)|*.*") );
132 Operations on properties should be done either via wxPropertyGrid's
133 (or wxPropertyGridManager's) methods, or by acquiring pointer to a property
134 (Append returns a wxPGProperty* or wxPGId, which is typedef for same), and then
135 calling its method. Note however that property's methods generally do not
136 automatically update grid graphics.
138 Property container functions operating on properties, such as SetPropertyValue or
139 DisableProperty, all accept a special wxPGPropArg, argument which can automatically
140 convert name of a property to a pointer. For instance:
143 // A file selector property.
144 wxPGPropety* p = pg->Append( new wxFileProperty(wxT("FileProperty"), wxPG_LABEL, wxEmptyString) );
146 // Valid: Set wildcard by name
147 pg->SetPropertyAttribute( wxT("FileProperty"),
149 wxT("All files (*.*)|*.*") );
151 // Also Valid: Set wildcard by ptr
152 pg->SetPropertyAttribute( p,
154 wxT("All files (*.*)|*.*") );
157 Using pointer is faster, since it doesn't require hash map lookup. Anyway, you can allways
158 get property pointer (wxPGProperty*) as Append/Insert return value, or by calling
161 Below are samples for using some of the more commong operations. See
162 wxPropertyGridInterface and wxPropertyGrid class references for complete list.
166 // wxPGId is a short-hand for wxPGProperty*. Let's use it this time.
167 wxPGId id = pg->GetPropertyByName( wxT("MyProperty") );
169 // There are many overloaded versions of this method, of which each accept
170 // different type of value.
171 pg->SetPropertyValue( wxT("MyProperty"), 200 );
173 // Setting a string works for all properties - conversion is done
175 pg->SetPropertyValue( id, wxT("400") );
177 // Getting property value as wxVariant.
178 wxVariant value = pg->GetPropertyValue( wxT("MyProperty") );
180 // Getting property value as String (again, works for all typs).
181 wxString value = pg->GetPropertyValueAsString( id );
183 // Getting property value as int. Provokes a run-time error
184 // if used with property which value type is not "long".
185 long value = pg->GetPropertyValueAsLong( wxT("MyProperty") );
188 pg->SetPropertyName( wxT("MyProperty"), wxT("X") );
190 // Set new label - we need to use the new name.
191 pg->SetPropertyLabel( wxT("X"), wxT("New Label") );
193 // Disable the property. It's text will appear greyed.
194 // This is probably the closest you can get if you want
195 // a "read-only" property.
196 pg->DisableProperty( id );
201 @section categories Categories
203 wxPropertyGrid has a hierarchial property storage and display model, which
204 allows property categories to hold child properties and even other
205 categories. Other than that, from the programmer's point of view, categories
206 can be treated exactly the same as "other" properties. For example, despite
207 its name, GetPropertyByName also returns a category by name, and SetPropertyLabel
208 also sets label of a category. Note however that sometimes the label of a
209 property category may be referred as caption (for example, there is
210 SetCaptionForegroundColour method that sets text colour of a property category's label).
212 When category is added at the top (i.e. root) level of the hierarchy,
213 it becomes a *current category*. This means that all other (non-category)
214 properties after it are automatically added to it. You may add
215 properties to specific categories by using wxPropertyGrid::Insert or wxPropertyGrid::AppendIn.
217 Category code sample:
221 // One way to add category (similar to how other properties are added)
222 pg->Append( new wxPropertyCategory(wxT("Main")) );
224 // All these are added to "Main" category
225 pg->Append( new wxStringProperty(wxT("Name")) );
226 pg->Append( new wxIntProperty(wxT("Age"),wxPG_LABEL,25) );
227 pg->Append( new wxIntProperty(wxT("Height"),wxPG_LABEL,180) );
228 pg->Append( new wxIntProperty(wxT("Weight")) );
231 pg->Append( new wxPropertyCategory(wxT("Attrikbutes")) );
233 // All these are added to "Attributes" category
234 pg->Append( new wxIntProperty(wxT("Intelligence")) );
235 pg->Append( new wxIntProperty(wxT("Agility")) );
236 pg->Append( new wxIntProperty(wxT("Strength")) );
241 @section parentprops Tree-like Property Structure
243 As a new feature in version 1.3.1, basicly any property can have children. There
244 are few limitations, however.
247 - Names of properties with non-category, non-root parents are not stored in hash map.
248 Instead, they can be accessed with strings like "Parent.Child". For instance, in
249 the sample below, child property named "Max. Speed (mph)" can be accessed by global
250 name "Car.Speeds.Max Speed (mph)".
251 - If you want to property's value to be a string composed based on the values of
252 child properties, you must use wxStringProperty as parent and use value "<composed>".
253 - Events (eg. change of value) that occur in parent do not propagate to children. Events
254 that occur in children will propagate to parents, but only if they are wxStringProperties
255 with "<composed>" value.
256 - Old wxParentProperty class is deprecated, and remains as a typedef of wxStringProperty.
257 If you want old value behavior, you must specify "<composed>" as wxStringProperty's
263 wxPGId pid = pg->Append( new wxStringProperty(wxT("Car"),wxPG_LABEL,wxT("<composed>")) );
265 pg->AppendIn( pid, new wxStringProperty(wxT("Model"),
267 wxT("Lamborghini Diablo SV")) );
269 pg->AppendIn( pid, new wxIntProperty(wxT("Engine Size (cc)"),
273 wxPGId speedId = pg->AppendIn( pid, new wxStringProperty(wxT("Speeds"),wxPG_LABEL,wxT("<composed>")) );
274 pg->AppendIn( speedId, new wxIntProperty(wxT("Max. Speed (mph)"),wxPG_LABEL,290) );
275 pg->AppendIn( speedId, new wxFloatProperty(wxT("0-100 mph (sec)"),wxPG_LABEL,3.9) );
276 pg->AppendIn( speedId, new wxFloatProperty(wxT("1/4 mile (sec)"),wxPG_LABEL,8.6) );
278 // Make sure the child properties can be accessed correctly
279 pg->SetPropertyValue( wxT("Car.Speeds.Max. Speed (mph)"), 300 );
281 pg->AppendIn( pid, new wxIntProperty(wxT("Price ($)"),
284 // Displayed value of "Car" property is now:
285 // "Lamborghini Diablo SV; [300; 3.9; 8.6]; 300000"
289 @section enumandflags wxEnumProperty and wxFlagsProperty
291 wxEnumProperty is used when you want property's (integer or string) value
292 to be selected from a popup list of choices.
294 Creating wxEnumProperty is more complex than those described earlier.
295 You have to provide list of constant labels, and optionally relevant values
296 (if label indexes are not sufficient).
300 - Value wxPG_INVALID_VALUE (equals 2147483647 which usually equals INT_MAX) is not
303 A very simple example:
308 // Using wxArrayString
310 wxArrayString arrDiet;
311 arr.Add(wxT("Herbivore"));
312 arr.Add(wxT("Carnivore"));
313 arr.Add(wxT("Omnivore"));
315 pg->Append( new wxEnumProperty(wxT("Diet"),
322 // Using wxChar* array
324 const wxChar* arrayDiet[] =
325 { wxT("Herbivore"), wxT("Carnivore"), wxT("Omnivore"), NULL };
327 pg->Append( new wxEnumProperty(wxT("Diet"),
334 Here's extended example using values as well:
339 // Using wxArrayString and wxArrayInt
341 wxArrayString arrDiet;
342 arr.Add(wxT("Herbivore"));
343 arr.Add(wxT("Carnivore"));
344 arr.Add(wxT("Omnivore"));
351 // Note that the initial value (the last argument) is the actual value,
352 // not index or anything like that. Thus, our value selects "Omnivore".
353 pg->Append( new wxEnumProperty(wxT("Diet"),
361 // Using wxChar* and long arrays
363 const wxChar* array_diet[] =
364 { wxT("Herbivore"), wxT("Carnivore"), wxT("Omnivore"), NULL };
366 long array_diet_ids[] =
369 // Value can be set from string as well
370 pg->Append( new wxEnumProperty(wxT("Diet"),
377 wxPGChoices is a class where wxEnumProperty, and other properties which
378 require label storage, actually stores strings and values. It is used
379 to facilitiate reference counting, and therefore recommended way of
380 adding items when multiple properties share the same set.
382 You can use wxPGChoices directly as well, filling it and then passing it
383 to the constructor. Infact, if you wish to display bitmaps next to labels,
384 your best choice is to use this approach.
389 chs.Add(wxT("Herbivore"),40);
390 chs.Add(wxT("Carnivore"),45);
391 chs.Add(wxT("Omnivore"),50);
393 // Let's add an item with bitmap, too
394 chs.Add(wxT("None of the above"), wxBitmap(), 60);
396 // Note: you can add even whole arrays to wxPGChoices
398 pg->Append( new wxEnumProperty(wxT("Diet"),
402 // Add same choices to another property as well - this is efficient due
403 // to reference counting
404 pg->Append( new wxEnumProperty(wxT("Diet 2"),
410 If you later need to change choices used by a property, there is function
416 // Example 1: Add one extra item
417 wxPGChoices& choices = pg->GetPropertyChoices(wxT("Diet"));
418 choices.Add(wxT("Custom"),55);
421 // Example 2: Replace all the choices
423 chs.Add(wxT("<No valid items yet>"),0);
424 pg->SetPropertyChoices(wxT("Diet"),chs);
428 If you want to create your enum properties with simple (label,name,value)
429 constructor, then you need to create a new property class using one of the
430 supplied macro pairs. See @ref newprops for details.
432 <b>wxEditEnumProperty</b> is works exactly like wxEnumProperty, except
433 is uses non-readonly combobox as default editor, and value is stored as
434 string when it is not any of the choices.
436 wxFlagsProperty is similar:
440 const wxChar* flags_prop_labels[] = { wxT("wxICONIZE"),
441 wxT("wxCAPTION"), wxT("wxMINIMIZE_BOX"), wxT("wxMAXIMIZE_BOX"), NULL };
443 // this value array would be optional if values matched string indexes
444 long flags_prop_values[] = { wxICONIZE, wxCAPTION, wxMINIMIZE_BOX,
447 pg->Append( new wxFlagsProperty(wxT("Window Style"),
451 wxDEFAULT_FRAME_STYLE) );
455 wxFlagsProperty can use wxPGChoices just the same way as wxEnumProperty
456 (and also custom property classes can be created with similar macro pairs).
457 <b>Note: </b> When changing "choices" (ie. flag labels) of wxFlagsProperty,
458 you will need to use SetPropertyChoices - otherwise they will not get updated
461 @section advprops Specialized Properties
463 This section describes the use of less often needed property classes.
464 To use them, you have to include <wx/propgrid/advprops.h>.
468 // Necessary extra header file
469 #include <wx/propgrid/advprops.h>
474 pg->Append( new wxDateProperty(wxT("MyDateProperty"),
476 wxDateTime::Now()) );
478 // Image file property. Wildcard is auto-generated from available
479 // image handlers, so it is not set this time.
480 pg->Append( new wxImageFileProperty(wxT("Label of ImageFileProperty"),
481 wxT("NameOfImageFileProp")) );
483 // Font property has sub-properties. Note that we give window's font as
485 pg->Append( new wxFontProperty(wxT("Font"),
489 // Colour property with arbitrary colour.
490 pg->Append( new wxColourProperty(wxT("My Colour 1"),
492 wxColour(242,109,0) ) );
494 // System colour property.
495 pg->Append( new wxSystemColourProperty(wxT("My SysColour 1"),
497 wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)) );
499 // System colour property with custom colour.
500 pg->Append( new wxSystemColourProperty(wxT("My SysColour 2"),
502 wxColour(0,200,160) ) );
505 pg->Append( new wxCursorProperty(wxT("My Cursor"),
512 @section iterating Iterating through a property container
514 You can use somewhat STL'ish iterator classes to iterate through the grid.
515 Here is a simple example of forward iterating through all individual
516 properties (not categories or sub-propeties that are normally 'transparent'
517 to application code):
521 wxPropertyGridIterator it;
523 for ( it = pg->GetIterator();
527 wxPGProperty* p = *it;
528 // Do something with the property
533 As expected there is also a const iterator:
537 wxPropertyGridConstIterator it;
539 for ( it = pg->GetIterator();
543 const wxPGProperty* p = *it;
544 // Do something with the property
549 You can give some arguments to GetIterator to determine which properties
550 get automatically filtered out. For complete list of options, see
551 @link iteratorflags List of Property Iterator Flags@endlink. GetIterator()
552 also accepts other arguments. See wxPropertyGridInterface::GetIterator()
555 This example reverse-iterates through all visible items:
559 wxPropertyGridIterator it;
561 for ( it = pg->GetIterator(wxPG_ITERATE_VISIBLE, wxBOTTOM);
565 wxPGProperty* p = *it;
566 // Do something with the property
571 <b>wxPython Note:</b> Instead of ++ operator, use Next() method, and instead of
572 * operator, use GetProperty() method.
574 GetIterator() only works with wxPropertyGrid and the individual pages
575 of wxPropertyGridManager. In order to iterate through an arbitrary
576 property container, you need to use wxPropertyGridInterface::GetVIterator().
577 Note however that this virtual iterater is limited to forward iteration.
583 for ( it = manager->GetVIterator();
587 wxPGProperty* p = it.GetProperty();
588 // Do something with the property
594 @section operations More About Operating with Properties
596 Getting value of selected wxSystemColourProperty (which value type is derived
601 wxPGId id = pg->GetSelection();
605 // Get name of property
606 const wxString& name = pg->GetPropertyName( id );
608 // If type is not correct, GetColour() method will produce run-time error
609 if ( pg->GetPropertyValueType() == wxT("wxColourPropertyValue") ) )
611 wxColourPropertyValue* pcolval =
612 wxDynamicCast(pg->GetPropertyValueAsWxObjectPtr(id),
613 wxColourPropertyValue);
617 if ( pcolval->m_type == wxPG_CUSTOM_COLOUR )
618 text.Printf( wxT("It is custom colour: (%i,%i,%i)"),
619 (int)pcolval->m_colour.Red(),
620 (int)pcolval->m_colour.Green(),
621 (int)pcolval->m_colour.Blue());
623 text.Printf( wxT("It is wx system colour (number=%i): (%i,%i,%i)"),
624 (int)pcolval->m_type,
625 (int)pcolval->m_colour.Red(),
626 (int)pcolval->m_colour.Green(),
627 (int)pcolval->m_colour.Blue());
629 wxMessageBox( text );
635 @section populating Populating wxPropertyGrid Automatically
637 @subsection fromvariants Populating from List of wxVariants
639 Example of populating an empty wxPropertyGrid from a values stored
640 in an arbitrary list of wxVariants.
644 // This is a static method that initializes *all* builtin type handlers
645 // available, including those for wxColour and wxFont. Refers to *all*
646 // included properties, so when compiling with static library, this
647 // method may increase the executable size significantly.
648 pg->InitAllTypeHandlers();
650 // Get contents of the grid as a wxVariant list
651 wxVariant all_values = pg->GetPropertyValues();
653 // Populate the list with values. If a property with appropriate
654 // name is not found, it is created according to the type of variant.
655 pg->SetPropertyValues( my_list_variant );
657 // In order to get wxObject ptr from a variant value,
658 // wxGetVariantCast(VARIANT,CLASSNAME) macro has to be called.
660 wxVariant v_txcol = pg->GetPropertyValue(wxT("Text Colour"));
661 const wxColour& txcol = wxGetVariantCast(v_txcol,wxColour);
665 @subsection fromfile Loading Population from a Text-based Storage
667 Class wxPropertyGridPopulator may be helpful when writing code that
668 loads properties from a text-source. In fact, the supplied xrc handler
669 (src/xh_propgrid.cpp) uses it. See that code for more info.
670 NOTE: src/xh_propgrid.cpp is not included in the library by default,
671 to avoid dependency to wxXRC. You will need to add it to your application
674 @subsection editablestate Saving and Restoring User-Editable State
676 You can use wxPGEditableState and wxPGMEditableState classes, and
677 wxPropertyGrid::SaveEditableState() and wxPropertyGrid::RestoreEditableState()
678 to save and restore user-editable state (selected property, expanded/
679 collapsed properties, and scrolled position). For convience with
680 program configuration, wxPGEditableState has functions to save/load
681 its value in wxString. For instance:
684 // Save state into config
685 wxPGEditableState edState;
686 pg->SaveEditableState(&edState);
687 programConfig->Store(wxT("PropertyGridState"), edState.GetAsString());
689 // Restore state from config
690 wxPGEditableState edState;
691 edState.SetFromString(programConfig->Load(wxT("PropertyGridState")));
692 pg->RestoreEditableState(edState);
696 @section events Event Handling
698 Probably the most important event is the Changed event which occurs when
699 value of any property is changed by the user. Use EVT_PG_CHANGED(id,func)
700 in your event table to use it.
702 For complete list of event types, see wxPropertyGrid class reference.
704 The custom event class, wxPropertyGridEvent, has methods to directly
705 access the property that triggered the event.
707 Here's a small sample:
711 // Portion of an imaginary event table
712 BEGIN_EVENT_TABLE(MyForm, wxFrame)
716 // This occurs when a property value changes
717 EVT_PG_CHANGED( PGID, MyForm::OnPropertyGridChange )
723 void MyForm::OnPropertyGridChange( wxPropertyGridEvent& event )
725 wxPGProperty *property = event.GetProperty();
731 // Get name of changed property
732 const wxString& name = property->GetName();
734 // Get resulting value
735 wxVariant value = property->GetValue();
740 Another event type you might find useful is EVT_PG_CHANGING, which occurs
741 just prior property value is being changed by user. You can acquire pending
742 value using wxPropertyGridEvent::GetValue(), and if it is not acceptable,
743 call wxPropertyGridEvent::Veto() to prevent the value change from taking
748 // Portion of an imaginary event table
749 BEGIN_EVENT_TABLE(MyForm, wxFrame)
753 // This occurs when a property value changes
754 EVT_PG_CHANGING( PGID, MyForm::OnPropertyGridChanging )
760 void MyForm::OnPropertyGridChanging( wxPropertyGridEvent& event )
762 wxPGProperty* property = event.GetProperty();
764 if ( property == m_pWatchThisProperty )
766 // GetValue() returns the pending value, but is only
767 // supported by wxEVT_PG_CHANGING.
768 if ( event.GetValue().GetString() == g_pThisTextIsNotAllowed )
778 @remarks On Sub-property Event Handling
779 - For aggregate type properties (wxFontProperty, wxFlagsProperty, etc), events
780 occur for the main parent property only. For other properties events occur
781 for the children themselves..
783 - When property's child gets changed, you can use wxPropertyGridEvent::GetMainParent
784 to obtain its topmost non-category parent (useful, if you have deeply nested
788 @section validating Validating Property Values
790 There are various ways to make sure user enters only correct values. First, you
791 can use wxValidators similar to as you would with ordinary controls. Use
792 wxPropertyGridInterface::SetPropertyValidator() to assign wxValidator to
795 Second, you can subclass a property and override wxPGProperty::ValidateValue(),
796 or handle wxEVT_PG_CHANGING for the same effect. Both of these methods do not
797 actually prevent user from temporarily entering invalid text, but they do give
798 you an opportunity to warn the user and block changed value from being committed
801 Various validation failure options can be controlled globally with
802 wxPropertyGrid::SetValidationFailureBehavior(), or on an event basis by
803 calling wxEvent::SetValidationFailureBehavior(). Here's a code snippet of
804 how to handle wxEVT_PG_CHANGING, and to set custom failure behaviour and
808 void MyFrame::OnPropertyGridChanging(wxPropertyGridEvent& event)
810 wxPGProperty* property = event.GetProperty();
812 // You must use wxPropertyGridEvent::GetValue() to access
813 // the value to be validated.
814 wxVariant pendingValue = event.GetValue();
816 if ( property->GetName() == wxT("Font") )
818 // Make sure value is not unspecified
819 if ( !pendingValue.IsNull() )
821 wxFont font << pendingValue;
823 // Let's just allow Arial font
824 if ( font.GetFaceName() != wxT("Arial") )
827 event.SetValidationFailureBehavior(wxPG_VFB_STAY_IN_PROPERTY |
829 wxPG_VFB_SHOW_MESSAGE);
837 @section cellrender Customizing Individual Cell Appearance
839 You can control text colour, background colour, and attached image of
840 each cell in the property grid. Use wxPropertyGridInterface::SetPropertyCell() or
841 wxPGProperty::SetCell() for this purpose.
843 In addition, it is possible to control these characteristics for
844 wxPGChoices list items. See wxPGChoices::Item() and wxPGChoiceEntry class
845 reference for more info.
848 @section customizing Customizing Properties (without sub-classing)
850 In this section are presented miscellaneous ways to have custom appearance
851 and behavior for your properties without all the necessary hassle
852 of sub-classing a property class etc.
854 @subsection customimage Setting Value Image
856 Every property can have a small value image placed in front of the
857 actual value text. Built-in example of this can be seen with
858 wxColourProperty and wxImageFileProperty, but for others it can
859 be set using wxPropertyGrid::SetPropertyImage method.
861 @subsection customvalidator Setting Validator
863 You can set wxValidator for a property using wxPropertyGrid::SetPropertyValidator.
865 Validator will work just like in wxWidgets (ie. editorControl->SetValidator(validator)
868 @subsection customeditor Setting Property's Editor Control(s)
870 You can set editor control (or controls, in case of a control and button),
871 of any property using wxPropertyGrid::SetPropertyEditor. Editors are passed
872 using wxPG_EDITOR(EditorName) macro, and valid built-in EditorNames are
873 TextCtrl, Choice, ComboBox, CheckBox, TextCtrlAndButton, ChoiceAndButton,
874 SpinCtrl, and DatePickerCtrl. Two last mentioned ones require call to
875 static member function wxPropertyGrid::RegisterAdditionalEditors().
877 Following example changes wxColourProperty's editor from default Choice
878 to TextCtrlAndButton. wxColourProperty has its internal event handling set
879 up so that button click events of the button will be used to trigger
880 colour selection dialog.
884 wxPGId colProp = pg->Append(wxColourProperty(wxT("Text Colour")));
886 pg->SetPropertyEditor(colProp,wxPG_EDITOR(TextCtrlAndButton));
890 Naturally, creating and setting custom editor classes is a possibility as
891 well. For more information, see wxPGEditor class reference.
893 @subsection editorattrs Property Attributes Recognized by Editors
895 <b>SpinCtrl</b> editor can make use of property's "Min", "Max", "Step" and "Wrap" attributes.
897 @subsection multiplebuttons Adding Multiple Buttons Next to an Editor
899 See wxPGMultiButton class reference.
901 @subsection customeventhandling Handling Events Passed from Properties
903 <b>wxEVT_COMMAND_BUTTON_CLICKED </b>(corresponds to event table macro EVT_BUTTON):
904 Occurs when editor button click is not handled by the property itself
905 (as is the case, for example, if you set property's editor to TextCtrlAndButton
906 from the original TextCtrl).
908 @subsection attributes Property Attributes
910 Miscellaneous values, often specific to a property type, can be set
911 using wxPropertyGrid::SetPropertyAttribute and wxPropertyGrid::SetPropertyAttributeAll
914 Attribute names are strings and values wxVariant. Arbitrary names are allowed
915 inorder to store user values. Constant equivalents of all attribute string names are
916 provided. Some of them are defined as cached strings, so using constants can provide
917 for smaller binary size.
919 For complete list of attributes, see @link attrids Property Attributes@endlink.
921 @subsection boolcheckbox Setting wxBoolProperties to Use Check Box
923 To have all wxBoolProperties to use CheckBox editor instead of Choice, use
924 following (call after bool properties have been added):
927 pg->SetPropertyAttributeAll(wxPG_BOOL_USE_CHECKBOX,true);
931 @section usage2 Using wxPropertyGridManager
933 wxPropertyGridManager is an efficient multi-page version of wxPropertyGrid,
934 which can optionally have toolbar for mode and page selection, and a help text
937 wxPropertyGridManager inherits from wxPropertyGridInterface, and as such
938 it has most property manipulation functions. However, only some of them affect
939 properties on all pages (eg. GetPropertyByName() and ExpandAll()), while some
940 (eg. Append()) only apply to the currently selected page.
942 To operate explicitly on properties on specific page, use wxPropertyGridManager::GetPage()
943 to obtain pointer to page's wxPropertyGridPage object.
945 Visual methods, such as SetCellBackgroundColour and GetNextVisible are only
946 available in wxPropertyGrid. Use wxPropertyGridManager::GetGrid() to obtain
949 Iteration methods will not work in wxPropertyGridManager. Instead, you must acquire
950 the internal grid (GetGrid()) or wxPropertyGridPage object (GetPage()).
952 wxPropertyGridManager constructor has exact same format as wxPropertyGrid
953 constructor, and basicly accepts same extra window style flags (albeit also
954 has some extra ones).
956 Here's some example code for creating and populating a wxPropertyGridManager:
960 wxPropertyGridManager* pgMan = new wxPropertyGridManager(this, PGID,
961 wxDefaultPosition, wxDefaultSize,
962 // These and other similar styles are automatically
963 // passed to the embedded wxPropertyGrid.
964 wxPG_BOLD_MODIFIED|wxPG_SPLITTER_AUTO_CENTER|
967 // Include description box.
969 // Include compactor.
972 wxPGMAN_DEFAULT_STYLE
975 wxPropertyGridPage* page;
977 // Adding a page sets target page to the one added, so
978 // we don't have to call SetTargetPage if we are filling
979 // it right after adding.
980 pgMan->AddPage(wxT("First Page"));
981 page = pgMan->GetLastPage();
983 page->Append( new wxPropertyCategory(wxT("Category A1")) );
985 page->Append( new wxIntProperty(wxT("Number"),wxPG_LABEL,1) );
987 page->Append( new wxColourProperty(wxT("Colour"),wxPG_LABEL,*wxWHITE) );
989 pgMan->AddPage(wxT("Second Page"));
990 page = pgMan->GetLastPage();
992 page->Append( wxT("Text"),wxPG_LABEL,wxT("(no text)") );
994 page->Append( new wxFontProperty(wxT("Font"),wxPG_LABEL) );
998 @subsection propgridpage wxPropertyGridPage
1000 wxPropertyGridPage is holder of properties for one page in manager. It is derived from
1001 wxEvtHandler, so you can subclass it to process page-specific property grid events. Hand
1002 over your page instance in wxPropertyGridManager::AddPage.
1004 Please note that the wxPropertyGridPage itself only sports subset of wxPropertyGrid API
1005 (but unlike manager, this include item iteration). Naturally it inherits from
1006 wxPropertyGridMethods and wxPropertyGridPageState.
1009 @section subclassing Subclassing wxPropertyGrid and wxPropertyGridManager
1013 - Only a small percentage of member functions are virtual. If you need more,
1014 just e-mail to wx-dev mailing list.
1016 - Data manipulation is done in wxPropertyGridPageState class. So, instead of
1017 overriding wxPropertyGrid::Insert, you'll probably want to override wxPropertyGridPageState::DoInsert.
1019 - Override wxPropertyGrid::CreateState to instantiate your derivate wxPropertyGridPageState.
1020 For wxPropertyGridManager, you'll need to subclass wxPropertyGridPage instead (since it
1021 is derived from wxPropertyGridPageState), and hand over instances in wxPropertyGridManager::AddPage
1024 - You can use a derivate wxPropertyGrid with manager by overriding wxPropertyGridManager::CreatePropertyGrid
1028 @section misc Miscellaneous Topics
1030 @subsection namescope Property Name Scope
1032 - All properties which parent is category or root have their names
1033 globally accessible.
1035 - Sub-properties (i.e. private child properties which have parent that is not category or
1036 root or non-aggregate property) can not be accessed globally by their name. Instead, use
1037 "<property>.<subproperty>".
1039 @subsection boolproperty wxBoolProperty
1041 There are few points about wxBoolProperty that require futher discussion:
1042 - wxBoolProperty can be shown as either normal combobox or as a checkbox.
1043 Property attribute wxPG_BOOL_USE_CHECKBOX is used to change this.
1044 For example, if you have a wxFlagsProperty, you can
1045 set its all items to use check box using the following:
1047 pg->SetPropertyAttribute(wxT("MyFlagsProperty"),wxPG_BOOL_USE_CHECKBOX,true,wxPG_RECURSE);
1050 - Default item names for wxBoolProperty are [wxT("False"),wxT("True")]. This can be
1051 changed using wxPropertyGrid::SetBoolChoices(trueChoice,falseChoice).
1053 @subsection textctrlupdates Updates from wxTextCtrl Based Editor
1055 Changes from wxTextCtrl based property editors are committed (ie.
1056 wxEVT_PG_CHANGED is sent etc.) *only* when (1) user presser enter, (2)
1057 user moves to edit another property, or (3) when focus leaves
1060 Because of this, you may find it useful, in some apps, to call
1061 wxPropertyGrid::CommitChangesFromEditor() just before you need to do any
1062 computations based on property grid values. Note that CommitChangesFromEditor()
1063 will dispatch wxEVT_PG_CHANGED with ProcessEvent, so any of your event handlers
1064 will be called immediately.
1066 @subsection splittercentering Centering the Splitter
1068 If you need to center the splitter, but only once when the program starts,
1069 then do <b>not</b> use the wxPG_SPLITTER_AUTO_CENTER window style, but the
1070 wxPropertyGrid::CenterSplitter() method. <b>However, be sure to call it after
1071 the sizer setup and SetSize calls!</b> (ie. usually at the end of the
1072 frame/dialog constructor)
1074 @subsection splittersetting Setting Splitter Position When Creating Property Grid
1076 Splitter position cannot exceed grid size, and therefore setting it during
1077 form creation may fail as initial grid size is often smaller than desired
1078 splitter position, especially when sizers are being used.
1080 @subsection colourproperty wxColourProperty and wxSystemColourProperty
1082 Through subclassing, these two property classes provide substantial customization
1083 features. Subclass wxSystemColourProperty if you want to use wxColourPropertyValue
1084 (which features colour type in addition to wxColour), and wxColourProperty if plain
1087 Override wxSystemColourProperty::ColourToString() to redefine how colours are
1090 Override wxSystemColourProperty::GetCustomColourIndex() to redefine location of
1091 the item that triggers colour picker dialog (default is last).
1093 Override wxSystemColourProperty::GetColour() to determine which colour matches
1096 @section proplist Property Class Descriptions
1098 See @ref pgproperty_properties