]>
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: @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 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 2147483647 which usually equals INT_MAX) is not
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 // Value can be set from string as well
369 pg->Append( new wxEnumProperty(wxT("Diet"),
376 wxPGChoices is a class where wxEnumProperty, and other properties which
377 require label storage, actually stores strings and values. It is used
378 to facilitiate reference counting, and therefore recommended way of
379 adding items when multiple properties share the same set.
381 You can use wxPGChoices directly as well, filling it and then passing it
382 to the constructor. Infact, if you wish to display bitmaps next to labels,
383 your best choice is to use this approach.
388 chs.Add(wxT("Herbivore"),40);
389 chs.Add(wxT("Carnivore"),45);
390 chs.Add(wxT("Omnivore"),50);
392 // Let's add an item with bitmap, too
393 chs.Add(wxT("None of the above"), wxBitmap(), 60);
395 // Note: you can add even whole arrays to wxPGChoices
397 pg->Append( new wxEnumProperty(wxT("Diet"),
401 // Add same choices to another property as well - this is efficient due
402 // to reference counting
403 pg->Append( new wxEnumProperty(wxT("Diet 2"),
409 If you later need to change choices used by a property, there is function
415 // Example 1: Add one extra item
416 wxPGChoices& choices = pg->GetPropertyChoices(wxT("Diet"));
417 choices.Add(wxT("Custom"),55);
420 // Example 2: Replace all the choices
422 chs.Add(wxT("<No valid items yet>"),0);
423 pg->SetPropertyChoices(wxT("Diet"),chs);
427 If you want to create your enum properties with simple (label,name,value)
428 constructor, then you need to create a new property class using one of the
429 supplied macro pairs. See @ref pgproperty_creating for details.
431 <b>wxEditEnumProperty</b> is works exactly like wxEnumProperty, except
432 is uses non-readonly combobox as default editor, and value is stored as
433 string when it is not any of the choices.
435 wxFlagsProperty is similar:
439 const wxChar* flags_prop_labels[] = { wxT("wxICONIZE"),
440 wxT("wxCAPTION"), wxT("wxMINIMIZE_BOX"), wxT("wxMAXIMIZE_BOX"), NULL };
442 // this value array would be optional if values matched string indexes
443 long flags_prop_values[] = { wxICONIZE, wxCAPTION, wxMINIMIZE_BOX,
446 pg->Append( new wxFlagsProperty(wxT("Window Style"),
450 wxDEFAULT_FRAME_STYLE) );
454 wxFlagsProperty can use wxPGChoices just the same way as wxEnumProperty
455 (and also custom property classes can be created with similar macro pairs).
456 <b>Note: </b> When changing "choices" (ie. flag labels) of wxFlagsProperty,
457 you will need to use SetPropertyChoices - otherwise they will not get updated
460 @section propgrid_advprops Specialized Properties
462 This section describes the use of less often needed property classes.
463 To use them, you have to include <wx/propgrid/advprops.h>.
467 // Necessary extra header file
468 #include <wx/propgrid/advprops.h>
473 pg->Append( new wxDateProperty(wxT("MyDateProperty"),
475 wxDateTime::Now()) );
477 // Image file property. Wildcard is auto-generated from available
478 // image handlers, so it is not set this time.
479 pg->Append( new wxImageFileProperty(wxT("Label of ImageFileProperty"),
480 wxT("NameOfImageFileProp")) );
482 // Font property has sub-properties. Note that we give window's font as
484 pg->Append( new wxFontProperty(wxT("Font"),
488 // Colour property with arbitrary colour.
489 pg->Append( new wxColourProperty(wxT("My Colour 1"),
491 wxColour(242,109,0) ) );
493 // System colour property.
494 pg->Append( new wxSystemColourProperty(wxT("My SysColour 1"),
496 wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)) );
498 // System colour property with custom colour.
499 pg->Append( new wxSystemColourProperty(wxT("My SysColour 2"),
501 wxColour(0,200,160) ) );
504 pg->Append( new wxCursorProperty(wxT("My Cursor"),
511 @section propgrid_iterating Iterating through a property container
513 You can use somewhat STL'ish iterator classes to iterate through the grid.
514 Here is a simple example of forward iterating through all individual
515 properties (not categories or sub-propeties that are normally 'transparent'
516 to application code):
520 wxPropertyGridIterator it;
522 for ( it = pg->GetIterator();
526 wxPGProperty* p = *it;
527 // Do something with the property
532 As expected there is also a const iterator:
536 wxPropertyGridConstIterator it;
538 for ( it = pg->GetIterator();
542 const wxPGProperty* p = *it;
543 // Do something with the property
548 You can give some arguments to GetIterator to determine which properties
549 get automatically filtered out. For complete list of options, see
550 @link iteratorflags List of Property Iterator Flags@endlink. GetIterator()
551 also accepts other arguments. See wxPropertyGridInterface::GetIterator()
554 This example reverse-iterates through all visible items:
558 wxPropertyGridIterator it;
560 for ( it = pg->GetIterator(wxPG_ITERATE_VISIBLE, wxBOTTOM);
564 wxPGProperty* p = *it;
565 // Do something with the property
570 <b>wxPython Note:</b> Instead of ++ operator, use Next() method, and instead of
571 * operator, use GetProperty() method.
573 GetIterator() only works with wxPropertyGrid and the individual pages
574 of wxPropertyGridManager. In order to iterate through an arbitrary
575 property container, you need to use wxPropertyGridInterface::GetVIterator().
576 Note however that this virtual iterater is limited to forward iteration.
582 for ( it = manager->GetVIterator();
586 wxPGProperty* p = it.GetProperty();
587 // Do something with the property
593 @section propgrid_operations More About Operating with Properties
595 Getting value of selected wxSystemColourProperty (which value type is derived
600 wxPGId id = pg->GetSelection();
604 // Get name of property
605 const wxString& name = pg->GetPropertyName( id );
607 // If type is not correct, GetColour() method will produce run-time error
608 if ( pg->GetPropertyValueType() == wxT("wxColourPropertyValue") ) )
610 wxColourPropertyValue* pcolval =
611 wxDynamicCast(pg->GetPropertyValueAsWxObjectPtr(id),
612 wxColourPropertyValue);
616 if ( pcolval->m_type == wxPG_CUSTOM_COLOUR )
617 text.Printf( wxT("It is custom colour: (%i,%i,%i)"),
618 (int)pcolval->m_colour.Red(),
619 (int)pcolval->m_colour.Green(),
620 (int)pcolval->m_colour.Blue());
622 text.Printf( wxT("It is wx system colour (number=%i): (%i,%i,%i)"),
623 (int)pcolval->m_type,
624 (int)pcolval->m_colour.Red(),
625 (int)pcolval->m_colour.Green(),
626 (int)pcolval->m_colour.Blue());
628 wxMessageBox( text );
634 @section propgrid_populating Populating wxPropertyGrid Automatically
636 @subsection propgrid_fromvariants Populating from List of wxVariants
638 Example of populating an empty wxPropertyGrid from a values stored
639 in an arbitrary list of wxVariants.
643 // This is a static method that initializes *all* builtin type handlers
644 // available, including those for wxColour and wxFont. Refers to *all*
645 // included properties, so when compiling with static library, this
646 // method may increase the executable size significantly.
647 pg->InitAllTypeHandlers();
649 // Get contents of the grid as a wxVariant list
650 wxVariant all_values = pg->GetPropertyValues();
652 // Populate the list with values. If a property with appropriate
653 // name is not found, it is created according to the type of variant.
654 pg->SetPropertyValues( my_list_variant );
656 // In order to get wxObject ptr from a variant value,
657 // wxGetVariantCast(VARIANT,CLASSNAME) macro has to be called.
659 wxVariant v_txcol = pg->GetPropertyValue(wxT("Text Colour"));
660 const wxColour& txcol = wxGetVariantCast(v_txcol,wxColour);
664 @subsection propgrid_fromfile Loading Population from a Text-based Storage
666 Class wxPropertyGridPopulator may be helpful when writing code that
667 loads properties from a text-source. In fact, the supplied xrc handler
668 (src/xh_propgrid.cpp) uses it. See that code for more info.
669 NOTE: src/xh_propgrid.cpp is not included in the library by default,
670 to avoid dependency to wxXRC. You will need to add it to your application
673 @subsection propgrid_editablestate Saving and Restoring User-Editable State
675 You can use wxPGEditableState and wxPGMEditableState classes, and
676 wxPropertyGrid::SaveEditableState() and wxPropertyGrid::RestoreEditableState()
677 to save and restore user-editable state (selected property, expanded/
678 collapsed properties, and scrolled position). For convience with
679 program configuration, wxPGEditableState has functions to save/load
680 its value in wxString. For instance:
683 // Save state into config
684 wxPGEditableState edState;
685 pg->SaveEditableState(&edState);
686 programConfig->Store(wxT("PropertyGridState"), edState.GetAsString());
688 // Restore state from config
689 wxPGEditableState edState;
690 edState.SetFromString(programConfig->Load(wxT("PropertyGridState")));
691 pg->RestoreEditableState(edState);
695 @section propgrid_events Event Handling
697 Probably the most important event is the Changed event which occurs when
698 value of any property is changed by the user. Use EVT_PG_CHANGED(id,func)
699 in your event table to use it.
701 For complete list of event types, see wxPropertyGrid class reference.
703 The custom event class, wxPropertyGridEvent, has methods to directly
704 access the property that triggered the event.
706 Here's a small sample:
710 // Portion of an imaginary event table
711 BEGIN_EVENT_TABLE(MyForm, wxFrame)
715 // This occurs when a property value changes
716 EVT_PG_CHANGED( PGID, MyForm::OnPropertyGridChange )
722 void MyForm::OnPropertyGridChange( wxPropertyGridEvent& event )
724 wxPGProperty *property = event.GetProperty();
730 // Get name of changed property
731 const wxString& name = property->GetName();
733 // Get resulting value
734 wxVariant value = property->GetValue();
739 Another event type you might find useful is EVT_PG_CHANGING, which occurs
740 just prior property value is being changed by user. You can acquire pending
741 value using wxPropertyGridEvent::GetValue(), and if it is not acceptable,
742 call wxPropertyGridEvent::Veto() to prevent the value change from taking
747 // Portion of an imaginary event table
748 BEGIN_EVENT_TABLE(MyForm, wxFrame)
752 // This occurs when a property value changes
753 EVT_PG_CHANGING( PGID, MyForm::OnPropertyGridChanging )
759 void MyForm::OnPropertyGridChanging( wxPropertyGridEvent& event )
761 wxPGProperty* property = event.GetProperty();
763 if ( property == m_pWatchThisProperty )
765 // GetValue() returns the pending value, but is only
766 // supported by wxEVT_PG_CHANGING.
767 if ( event.GetValue().GetString() == g_pThisTextIsNotAllowed )
777 @remarks On Sub-property Event Handling
778 - For aggregate type properties (wxFontProperty, wxFlagsProperty, etc), events
779 occur for the main parent property only. For other properties events occur
780 for the children themselves..
782 - When property's child gets changed, you can use wxPropertyGridEvent::GetMainParent
783 to obtain its topmost non-category parent (useful, if you have deeply nested
787 @section propgrid_validating Validating Property Values
789 There are various ways to make sure user enters only correct values. First, you
790 can use wxValidators similar to as you would with ordinary controls. Use
791 wxPropertyGridInterface::SetPropertyValidator() to assign wxValidator to
794 Second, you can subclass a property and override wxPGProperty::ValidateValue(),
795 or handle wxEVT_PG_CHANGING for the same effect. Both of these methods do not
796 actually prevent user from temporarily entering invalid text, but they do give
797 you an opportunity to warn the user and block changed value from being committed
800 Various validation failure options can be controlled globally with
801 wxPropertyGrid::SetValidationFailureBehavior(), or on an event basis by
802 calling wxEvent::SetValidationFailureBehavior(). Here's a code snippet of
803 how to handle wxEVT_PG_CHANGING, and to set custom failure behaviour and
807 void MyFrame::OnPropertyGridChanging(wxPropertyGridEvent& event)
809 wxPGProperty* property = event.GetProperty();
811 // You must use wxPropertyGridEvent::GetValue() to access
812 // the value to be validated.
813 wxVariant pendingValue = event.GetValue();
815 if ( property->GetName() == wxT("Font") )
817 // Make sure value is not unspecified
818 if ( !pendingValue.IsNull() )
820 wxFont font << pendingValue;
822 // Let's just allow Arial font
823 if ( font.GetFaceName() != wxT("Arial") )
826 event.SetValidationFailureBehavior(wxPG_VFB_STAY_IN_PROPERTY |
828 wxPG_VFB_SHOW_MESSAGE);
836 @section propgrid_cellrender Customizing Individual Cell Appearance
838 You can control text colour, background colour, and attached image of
839 each cell in the property grid. Use wxPropertyGridInterface::SetPropertyCell() or
840 wxPGProperty::SetCell() for this purpose.
842 In addition, it is possible to control these characteristics for
843 wxPGChoices list items. See wxPGChoices::Item() and wxPGChoiceEntry class
844 reference for more info.
847 @section propgrid_customizing Customizing Properties (without sub-classing)
849 In this section are presented miscellaneous ways to have custom appearance
850 and behavior for your properties without all the necessary hassle
851 of sub-classing a property class etc.
853 @subsection propgrid_customimage Setting Value Image
855 Every property can have a small value image placed in front of the
856 actual value text. Built-in example of this can be seen with
857 wxColourProperty and wxImageFileProperty, but for others it can
858 be set using wxPropertyGrid::SetPropertyImage method.
860 @subsection propgrid_customvalidator Setting Validator
862 You can set wxValidator for a property using wxPropertyGrid::SetPropertyValidator.
864 Validator will work just like in wxWidgets (ie. editorControl->SetValidator(validator)
867 @subsection propgrid_customeditor Setting Property's Editor Control(s)
869 You can set editor control (or controls, in case of a control and button),
870 of any property using wxPropertyGrid::SetPropertyEditor. Editors are passed
871 using wxPG_EDITOR(EditorName) macro, and valid built-in EditorNames are
872 TextCtrl, Choice, ComboBox, CheckBox, TextCtrlAndButton, ChoiceAndButton,
873 SpinCtrl, and DatePickerCtrl. Two last mentioned ones require call to
874 static member function wxPropertyGrid::RegisterAdditionalEditors().
876 Following example changes wxColourProperty's editor from default Choice
877 to TextCtrlAndButton. wxColourProperty has its internal event handling set
878 up so that button click events of the button will be used to trigger
879 colour selection dialog.
883 wxPGId colProp = pg->Append(wxColourProperty(wxT("Text Colour")));
885 pg->SetPropertyEditor(colProp,wxPG_EDITOR(TextCtrlAndButton));
889 Naturally, creating and setting custom editor classes is a possibility as
890 well. For more information, see wxPGEditor class reference.
892 @subsection propgrid_editorattrs Property Attributes Recognized by Editors
894 <b>SpinCtrl</b> editor can make use of property's "Min", "Max", "Step" and "Wrap" attributes.
896 @subsection propgrid_multiplebuttons Adding Multiple Buttons Next to an Editor
898 See wxPGMultiButton class reference.
900 @subsection propgrid_customeventhandling Handling Events Passed from Properties
902 <b>wxEVT_COMMAND_BUTTON_CLICKED </b>(corresponds to event table macro EVT_BUTTON):
903 Occurs when editor button click is not handled by the property itself
904 (as is the case, for example, if you set property's editor to TextCtrlAndButton
905 from the original TextCtrl).
907 @subsection propgrid_attributes Property Attributes
909 Miscellaneous values, often specific to a property type, can be set
910 using wxPropertyGrid::SetPropertyAttribute and wxPropertyGrid::SetPropertyAttributeAll
913 Attribute names are strings and values wxVariant. Arbitrary names are allowed
914 inorder to store user values. Constant equivalents of all attribute string names are
915 provided. Some of them are defined as cached strings, so using constants can provide
916 for smaller binary size.
918 For complete list of attributes, see @link attrids Property Attributes@endlink.
920 @subsection propgrid_boolcheckbox Setting wxBoolProperties to Use Check Box
922 To have all wxBoolProperties to use CheckBox editor instead of Choice, use
923 following (call after bool properties have been added):
926 pg->SetPropertyAttributeAll(wxPG_BOOL_USE_CHECKBOX,true);
930 @section propgrid_usage2 Using wxPropertyGridManager
932 wxPropertyGridManager is an efficient multi-page version of wxPropertyGrid,
933 which can optionally have toolbar for mode and page selection, and a help text
936 wxPropertyGridManager inherits from wxPropertyGridInterface, and as such
937 it has most property manipulation functions. However, only some of them affect
938 properties on all pages (eg. GetPropertyByName() and ExpandAll()), while some
939 (eg. Append()) only apply to the currently selected page.
941 To operate explicitly on properties on specific page, use wxPropertyGridManager::GetPage()
942 to obtain pointer to page's wxPropertyGridPage object.
944 Visual methods, such as SetCellBackgroundColour and GetNextVisible are only
945 available in wxPropertyGrid. Use wxPropertyGridManager::GetGrid() to obtain
948 Iteration methods will not work in wxPropertyGridManager. Instead, you must acquire
949 the internal grid (GetGrid()) or wxPropertyGridPage object (GetPage()).
951 wxPropertyGridManager constructor has exact same format as wxPropertyGrid
952 constructor, and basicly accepts same extra window style flags (albeit also
953 has some extra ones).
955 Here's some example code for creating and populating a wxPropertyGridManager:
959 wxPropertyGridManager* pgMan = new wxPropertyGridManager(this, PGID,
960 wxDefaultPosition, wxDefaultSize,
961 // These and other similar styles are automatically
962 // passed to the embedded wxPropertyGrid.
963 wxPG_BOLD_MODIFIED|wxPG_SPLITTER_AUTO_CENTER|
966 // Include description box.
968 // Include compactor.
971 wxPGMAN_DEFAULT_STYLE
974 wxPropertyGridPage* page;
976 // Adding a page sets target page to the one added, so
977 // we don't have to call SetTargetPage if we are filling
978 // it right after adding.
979 pgMan->AddPage(wxT("First Page"));
980 page = pgMan->GetLastPage();
982 page->Append( new wxPropertyCategory(wxT("Category A1")) );
984 page->Append( new wxIntProperty(wxT("Number"),wxPG_LABEL,1) );
986 page->Append( new wxColourProperty(wxT("Colour"),wxPG_LABEL,*wxWHITE) );
988 pgMan->AddPage(wxT("Second Page"));
989 page = pgMan->GetLastPage();
991 page->Append( wxT("Text"),wxPG_LABEL,wxT("(no text)") );
993 page->Append( new wxFontProperty(wxT("Font"),wxPG_LABEL) );
997 @subsection propgrid_propgridpage wxPropertyGridPage
999 wxPropertyGridPage is holder of properties for one page in manager. It is derived from
1000 wxEvtHandler, so you can subclass it to process page-specific property grid events. Hand
1001 over your page instance in wxPropertyGridManager::AddPage.
1003 Please note that the wxPropertyGridPage itself only sports subset of wxPropertyGrid API
1004 (but unlike manager, this include item iteration). Naturally it inherits from
1005 wxPropertyGridMethods and wxPropertyGridPageState.
1008 @section propgrid_subclassing Subclassing wxPropertyGrid and wxPropertyGridManager
1012 - Only a small percentage of member functions are virtual. If you need more,
1013 just e-mail to wx-dev mailing list.
1015 - Data manipulation is done in wxPropertyGridPageState class. So, instead of
1016 overriding wxPropertyGrid::Insert, you'll probably want to override wxPropertyGridPageState::DoInsert.
1018 - Override wxPropertyGrid::CreateState to instantiate your derivate wxPropertyGridPageState.
1019 For wxPropertyGridManager, you'll need to subclass wxPropertyGridPage instead (since it
1020 is derived from wxPropertyGridPageState), and hand over instances in wxPropertyGridManager::AddPage
1023 - You can use a derivate wxPropertyGrid with manager by overriding wxPropertyGridManager::CreatePropertyGrid
1027 @section propgrid_misc Miscellaneous Topics
1029 @subsection propgrid_namescope Property Name Scope
1031 All properties which parent is category or root can be accessed
1032 directly by their base name (ie. name given for property in its constructor).
1033 Other properties can be accessed via "ParentsName.BaseName" notation,
1034 Naturally, all property names should be unique.
1036 @subsection propgrid_nonuniquelabels Non-unique Labels
1038 It is possible to have properties with identical label under same parent.
1039 However, care must be taken to ensure that each property still has
1042 @subsection propgrid_boolproperty wxBoolProperty
1044 There are few points about wxBoolProperty that require futher discussion:
1045 - wxBoolProperty can be shown as either normal combobox or as a checkbox.
1046 Property attribute wxPG_BOOL_USE_CHECKBOX is used to change this.
1047 For example, if you have a wxFlagsProperty, you can
1048 set its all items to use check box using the following:
1050 pg->SetPropertyAttribute(wxT("MyFlagsProperty"),wxPG_BOOL_USE_CHECKBOX,true,wxPG_RECURSE);
1053 - Default item names for wxBoolProperty are [wxT("False"),wxT("True")]. This can be
1054 changed using wxPropertyGrid::SetBoolChoices(trueChoice,falseChoice).
1056 @subsection propgrid_textctrlupdates Updates from wxTextCtrl Based Editor
1058 Changes from wxTextCtrl based property editors are committed (ie.
1059 wxEVT_PG_CHANGED is sent etc.) *only* when (1) user presser enter, (2)
1060 user moves to edit another property, or (3) when focus leaves
1063 Because of this, you may find it useful, in some apps, to call
1064 wxPropertyGrid::CommitChangesFromEditor() just before you need to do any
1065 computations based on property grid values. Note that CommitChangesFromEditor()
1066 will dispatch wxEVT_PG_CHANGED with ProcessEvent, so any of your event handlers
1067 will be called immediately.
1069 @subsection propgrid_splittercentering Centering the Splitter
1071 If you need to center the splitter, but only once when the program starts,
1072 then do <b>not</b> use the wxPG_SPLITTER_AUTO_CENTER window style, but the
1073 wxPropertyGrid::CenterSplitter() method. <b>However, be sure to call it after
1074 the sizer setup and SetSize calls!</b> (ie. usually at the end of the
1075 frame/dialog constructor)
1077 @subsection propgrid_splittersetting Setting Splitter Position When Creating Property Grid
1079 Splitter position cannot exceed grid size, and therefore setting it during
1080 form creation may fail as initial grid size is often smaller than desired
1081 splitter position, especially when sizers are being used.
1083 @subsection propgrid_colourproperty wxColourProperty and wxSystemColourProperty
1085 Through subclassing, these two property classes provide substantial customization
1086 features. Subclass wxSystemColourProperty if you want to use wxColourPropertyValue
1087 (which features colour type in addition to wxColour), and wxColourProperty if plain
1090 Override wxSystemColourProperty::ColourToString() to redefine how colours are
1093 Override wxSystemColourProperty::GetCustomColourIndex() to redefine location of
1094 the item that triggers colour picker dialog (default is last).
1096 Override wxSystemColourProperty::GetColour() to determine which colour matches
1099 @section propgrid_proplist Property Class Descriptions
1101 See @ref pgproperty_properties