"We were looking for a property grid that integrates with the existing MS infrastructure and provides greater flexibility and efficiency in customization than MSPG. Fortunatly, we found VisualHint and SPG. Its rich features and steady enhancements together with a first class support not only make it an outstanding product, it makes it THE property grid for .NET."
VisualHint and Skybound have reached agreement on a technical partnership where both companies can share their expertise and code. The first impact for Smart PropertyGrid.Net is to allow better XP theme rendering for .Net 1.1 and 2.0 as well as the support of their incredible VisualTips which represent a must-have feature along value validation. Check Skybound products! They can be used for free or based on a premium subscription.
SPG.Net changelog
Version 3.1:
-----------
New features:
- With Smart FieldPackEditor, the PropertyGrid can show a totally new dropdown MonthCalendar for dates. It is localizable and can show Today and Clear buttons.
- The PropertyGrid.PropertyLabelBackColor and PropertyGrid.PropertyValueBackColor properties have been added to easily change the background of both columns in one shot.
- The PropertyGrid.AppendVariable() and InsertVariable() methods have been added to create properties targetting public variables.
- To move the PropertyGrid in the designer, you can now click anywhere in its bounds. Previously, you were obliged to click on the small top/left move icon.
- The PropertyGrid.ExpandAllMaxLevels property has been added to change the default maximum number of levels expanded under a single property when ExpandAllProperties is called.
- The static member variable PropInPlaceList.MinDropDownHeight has been added to allow you to increase the height of long lists in the dropdown part of the list inplace control.
- The static member variable PropInPlaceList.MaxDropDownWidth has been added to allow you to lower the width of large lists in the dropdown part of the list inplace control.
- The PropertyDescriptors property has been added to the PropertyValue class so that you can access every PropertyDescriptor of every target instance when SelectedObjects is used.
Bugs fixed:
- In RTL mode, dropdown UITypeEditors could not appear.
- In RTL mode, dropdown lists (list feels) were not left aligned with the property value.
- Dropdown lists (list feels) could be truncated on the right of the screen.
- In RTL mode, HitTest was not working for hyperlinks
- Various issues (mainly cosmetic) have been fixed when SPG is used from MFC code.
- At design-time, the columns widths (through the LabelColumnWidthRatio property) could be set differently than what was specified in the designer PropertyGrid.
- The handling of the Font as an ambiant property was not correct, i.e. setting the Font on the parent of the grid was not correctly inherited. Furthermode, the AutoScaleMode was not set, leading to a weird resizing behavior when modifying the font of the parent.
- There was a missing graphics.Dispose() call in the Trackbar inplace control.
- When the dropdown form of a UITypeEditor or List feel is visible, the Application.Idle event won't be fired (this is true in the Microsoft PropertyGrid too). SPG fixes that by reenabling this event if needed (set PropertyGrid.HandleIdleDuringDropDown to true).
- When closing a dropdown editor by double-clicking on another property, the value could be modified on the currently selected property which had the UITypeEditor opened, not the one double-clicked. This is fixed by not allowing a change on any of them.
- Using the PropertyComparerNoSort was removing some properties of the grid when targetting multiple instances.
- There was a crash when switching from flat to categorized display mode and a multiline property was partially visible at the top.
- When clicking on a property value of an unselected property, the mouse click was not propagated to the actual control of the inplace control under the mouse if there was more than one level of children.
- There was some problems with textbox autocompletion under Vista.
- Regression: in tabkey + autofocus mode, the text in an inplace control with a textbox was not selected anymore when selecting a property.
Version 3.0.1:
-------------
New features:
- The DisplayedValuesNeeded event can be triggered each time the dropdown window of a List feel is requested by the user. This is done with the new PropertyValue.ResetDisplayedValues(ResetDisplayedValuesTriggerMode) override.
- PropertyGrid.GetPropertyHashCode can be passed a flagged enumeration code to control what elements to include in the hashcode.
- The static variable AutoCompletionTimerDuration has been added to the PropertyGrid class so that you can change the duration used to reset the autocompletion buffer to empty after a key has been pressed.
- Autocompletion is switchable on/off on each property value.
- Performance has been increased when SPG is used with a large number (thousands) of target instances.
- The PropertyProgressLook class was only accepting integers. It now accepts all numeric types.
Bugs fixed:
- In the trackbar inplace control, the width of the textbox is calculated differently in order to avoid an occasional problem where the width is far too large.
- The calculation of a Property hashcode (in PropertyGrid.GetPropertyHashCode) had an error which could have a consequence in certain circumstances.
- In RTL mode, the dropdown button was reopening the dropdown box when clicked while the box was already open. It was also opening the box if the property was not selected yet (clicking on it while not selected).
- With the C++ compiler, the AttributeUsage attached to the PropertyAndChildrenAttribute class is not detected on subclasses, preventing to attach multiple instances of the same attribute to a property. The AttributeUsageAttribute has been restored on each child attribute.
- If a look class was specifying the bounds of the displayed string, some inplace control were not always respecting it.
- When adding a property to a disabled parent property, the new one was not set as disabled.
- The child properties of a parent property linked to a structure were not updated correctly if the structure was changed externally to SPG.
- The readonly state of properties was not always correct.
- The width of the columns was changing when the scrollbar needed to be shown (from an invisible state) or hidden (from a visible state).
- A VK_RETURN keystroke was generated when double clicking the label of a readonly property.
- The client application was not being notified for the key events of the PropInPlaceUITypeEditor class.
- With an updown inplace control, if the current value was equal to the minimum or maximum value of the underlying data type, hitting the down arrows was throwing an Overflow exception.
- The internal grid was not repositioned when the toolstrip's height was manually changed.
- The mouse wheel code was not using the SystemInformation.MouseWheelScrollLines information (set in the mouse driver by the user) to scroll the grid.
- Clipboard pasting could result in an invalid value in a non textbox based inplace control.
- In the Radio button inplace control, moving the mouse wheel was unexpectedly changing the selected radio button instead of just changing the focus cue.
- When using a SortedCategory attribute and a custom PropertyDescriptor overriding the Category property at the same time, the category name was grabbed from the attribute instead of the PropertyDescriptor.
- The PropertyFeelAttribute and PropertyLookAttribute classes were not detected when attached to a type instead of a property.
- In tabkey mode with autofocus submode set, clicking on the +/- glyph of an already selected category had no effect.
- After opening a resizable dropdown UITypeEditor, opening another non resizable UITypeEditor was setting its size incorrectly.
- The PropertyFontNameLook was displaying the value incorrectly in RightToLeft mode.
- The tooltip display was corrupted if larger than the screen (regression introduced in 3.0).
- When a TypeConverter publishes the properties of the target instance, the context passed to the GetProperties(Supported) methods was missing the Instance parameter.
Changes:
- PropertyValue.ResetDisplayedValues(bool) is now obsolete. Use PropertyValue.ResetDisplayedValues(ResetDisplayedValuesTriggerMode) instead.
Version 3.0:
-----------
New features:
- SPG supports right to left languages.
- SPG supports lazy loading (PropertyGrid.LazyLoading = true). It increases performance for large contents and solves the cyclic properties issue.
- SPG can now display an icon in front of any property value.
- Incremental search (typing letters one by one to get to the searched string) has been added to every textbox of properties having multiple displayed values (.Net 2.0+) and to the dropdown form of the list feel. It has even been added to listboxes found in external UITypeEditors i.e. you can type color or cursor names to find the one you want in the list.
- PropertyGrid.ShowDefaultValues uses DefaultValue attributes and ShouldSerialize methods to alter the font of the property values.
- The AlphaColorPicker class is now easily derivable and its alpha component can be turned off.
- The ResetDisplayedValues method and the DisplayedValuesNeeded event accept null strings in order to remove a possible value from the ones published by a TypeConverter. This is useful for enumerations for example in which you can now dynamically remove fields.
- The Editor and TypeConverter attributes can be set on a property at any time after the property has been created (with the PropertyValue.SetAttribute method).
- .Net 2.0+: The checkbox look and inplace control classes now support a nullable boolean type to create a 3-states checkbox (the undefined state can have its own string). It is possible to prevent the undefined state to be selected by the end-user.
- The PropertyGrid.ExpandAllProperties method can take a property enumerator in argument so that only the properties browsed by this enumerator will be expanded/collapsed.
- The '*' key expands all properties under the selected property (with a maximum depth of 10 to avoid infinite cycling). The '/' key collapses all properties under the selected property.
- The GetValueBackgroundColor virtual method has been added to the drawing manager class. It allows you to dynamically vary the value background color based on some criteria like the presence of multiple values for example.
- Tooltip is now ownerdrawn and can display italic fonts without truncation.
- When a property has an empty string in its possible displayed values, hitting Delete or Backspace when its label or inplace control is selected will select the empty displayed value.
- UpDownSettingsAttribute class has been added so that at designtime it's possible to set the increment of a property that uses the UpDown feel.
- PropertyDropDownContentAttribute can take additional arguments to be passed to the IDropDownContent implementation.
- A dropdown form (implementing IDropDownContent) can now close itself by calling it's parent's (PropInPlaceContainer) CloseDropDown method.
- PropertyGrid.ShowAdditionalIndentation creates an indentation more similar with the one of the Microsoft PropertyGrid.
- The PropertyGrid.AdjustComments method has been added to make the height of the comments area fit the test to be displayed.
- The button and UITypeEditor inplace controls can now display the button on the full width of the value column (use the FullWidthButton property). A ButtonSettingsAttribute class also allows to set this property at design-time. At last, a PropertyFullWidthButtonLook class has been added to ensure the button is always displayed on the property value.
Bugs fixed:
- Focus rectangles on updown and combobox inplace controls (those without a textbox) are better adjusted.
- When a property was disabled because it was readonly, calling PropertyValue.Recreate on this property was forcing all child properties to be disabled too. This was not correct in a lot of cases.
- The rectangle painted by the UITypeEditor.PaintValue method now respects the left margin (returned by PropertyGrid.GlobalTextMargin).
- Regression bug under .Net 1.1: non browsable properties (BrowsableAttribute set to false) were still visible in the grid.
- Depending on the font, the bullets displayed by the password look could be shifted by one pixel.
- When double-clicking the label of a property with an updown feel, the textbox was focused and the text was selected, which was not consistent with the other inplace control types.
- Checkboxes and radio buttons were not displayed in a disabled state when the grid was disabled.
- The ITypeDescriptorContext.Instance property was not always set correctly.
- It was not possible to set multiple TrackBarSettingsAttribute on a property for several children.
- PropertyValue.TypeConverter could return a brand new TypeConverter instead of relying on the one already owned by a PropertyDescriptor.
- Setting a PropertyIdAttribute on some but not all of the properties could result in various issues. SPG now ensures that two sibling properties won't have the same id in this case.
- The default alphabetical sort (controlled by the PropertyComparerDefaultSort class) could be wrong on property level > 1 if various Category attributes were applied to the sibling child properties of a parent property.
- SPG was crashing when removing the default buttons of the toolbar and calling PropertyGrid.DisplayMode.
- The MouseLeave event was not reported to a PropertyGrid derived class.
- When switching the display mode, the selected property tries to keep its position.
- There could be a crash in a trackbar inplace control if the trackbar becomes too small after resizing the grid (or the value column).
Changes:
- The PropertyLook.OnDraw and PropertyValue.DrawValue methods take an additional argument to know where the value is actually drawn.
- The PropertyValue.Recreate method has been replaced by the PropertyGrid.RecreateProperty method. The difference is that, before, only child properties were recreated. Now the property is actually deleted and completely recreated with the same logic than at its first creation.
- PropertyGrid.HitTest can now return Nowhere.
- The SelectedIndex that was passed in the PropertyChangedEventArgs has been removed. You can now access this information through PropertyValue.SelectedDisplayedValueIndex which will now work for any property and any feel using possible displayed values.
- CustomDrawManager.DrawCategoryLabelText and CustomDrawManager.DrawSubCategoryLabelText take an additional argument (the bounds of the whole row).
Version 2.5.3:
-------------
New features:
- Attaching an empty EditorAttribute to a property is now recognized and means "no editor". It allows for example to really force a collection property to be readonly.
- A virtual method GetPropertyHashCode has been added to the PropertyGrid class, so that it's possible for you to override the hashcode calculation used when saving and restoring property states during a grid refresh.
- The property display name and comment passed to AppendProperty-like methods can now be null. In this case, they will be determined from the attributes passed in parameter (.net 1.1 and 2.0+) or from the property descriptor (.net 2.0+).
Bugs fixed:
- When changing the value of a property, the internal Refresh of the grid (if any) is now more performant (it was previously always refreshing the whole grid).
- There was a crash if the TypeDescriptor.GetProperties or TypeConverter.GetProperties method is returning null (while GetPropertiesSupported() is returning true).
- An EditorAttribute set at runtime (with PropertyValue.SetAttribute()) had no effect.
- During a RestorePropertiesStates, usually called after RefreshProperties is finished, restoring the states of some properties whose value type has changed could fail. Therefore, the calculation of the property hashcode has been changed.
- During a RestorePropertiesStates, the selected property could shift to another row.
- During a RestorePropertiesStates, the HeightMultiplier of a property is now restored.
- During a refresh of the grid, if the selected property was recreated, the PropertySelected event could be triggered multiple times.
- If a get accessor of one of your properties was raising an exception, the grid was not catching it and a red cross was displayed.
- A property with a trackbar feel could not be set as readonly without crashing.
- Many fine-tunings on the management of the ReadOnly attribute.
- Regression: the trackbar inplace control was not resized when the width of the grid columns was changed.
- There was a crash when refreshing the content of the grid while the DisplayName of the selected property (or of an ancestor) was changed.
- If the grid was in a collapsible (auto-hide) panel, opening the dropdown list or editor of a property would close it immediately as well as close the panel.
- When changing the PropertyGrid's BorderStyle property, the scrollbar was resetted to position 0 and a bad page count.
- Regression bug: when in TabKey mode, clicking on the dropdown arrow to close the dropdown box of a UITypeEditor was modifying the value of the next property.
- TypeConverter.CanConvertFrom was not always called with a context (when determining if the property must be displayed as readonly).
- There was a crash when typing a key in an inplace control (for list, UITypeEditor, unit and updown feels) to directly choose one of the displayed values while an empty string is one of the possible values.
- If a category or subcategory was hidden in categorized display mode, switching to a flat display mode was revealing all descendant properties of the hidden category.
- When the content (total or part) of the grid was refreshed, hidden properties were reappearing.
- The "manually disabled checkbox" was not working on root categories.
- The dropdown form could not close if its new value was invalid (this was happening with the alpha color picker when choosing a transparent color for a property that could not accept transparent colors).
- Hidden properties were not taken into account when switching to flat mode. Therefore, a deep enumerator was unable to browse them.
- SPG was hanging when calling a set of methods while the grid's height was smaller than one property height. The scrollbar was also incorrectly setup in such a case.
- If a target instance was implementing ICustomTypeDescriptor, the Instance property passed through a ITypeDescriptorContext was referencing the object returned by the ICustomTypeDescriptor.GetPropertyOwner method instead of referencing the ICustomTypeDescriptor itself.
- Under Windows x64, an overflow exception could be raised (and internally caught) while typing keys.
- Regression: values changed in readonly textboxes inside UITypeEditors (by typing the up/down key or the first letter of a value) were not commited.
- A PropertyTypeDescriptorContext was not always passed to the UITypeEditor.GetEditStyle() method.
- Some weird obsolete code has been removed, creating a drastic increase in performance when filling the grid with SelectedObject(s).
- When using a custom PropertyComparer with multiple target instances, the sort order was invariably alphabetical.
- If a property had a ShowChildPropertiesAttribute(true) set, changing the value of the property would not recreate its children (with an obvious effect when changing the value to/from null).
- With an updown inplace control set to RealtimeChange=false, the value was still commited to the target property after the second click on the up/down buttons.
Version 2.5.2:
-------------
New features:
- The UITypeEditorVisualStyleAttribute class has been added so that you can override the button style of the editor.
- HyperLinkPropertyClicked events for hyperlink properties are now always generated (previously you got them only for single clicks).
Bugs fixed:
- The property descriptors published for a collection were alphabetically sorted (e.g. for an array it was sorting the child properties as [0], [1], [10], [11], [2], [20], ...).
- Adding a new property with a DisplayMode different than the Categorized mode now throws an exception instead of just asserting (which was visible just under debug mode).
- A property value of type String could be not updated correctly when edited by a UITypeEditor.
Version 2.5.1:
-------------
New features:
- The UITypeEditorTextBoxVisibility attribute has been added so that it's possible to remove the textbox for a UITypeEditor. A PropertyLook class could draw anything in the space left.
- The PropertyColorLook can draw the color box on the whole value column without the value text.
- The PropertyComparerDefaultSort class now queries the SortedProperty attribute attached to nested child properties. It removes the limitation that the grid was not able to handle the SortedProperty attribute set on child properties.
- A new attribute PreventRefreshProperties can be attached to a property if you want to prevent the RefreshProperties method to be called internally when the property value changes. Do it only if you are sure that the value change should not incur a change in the content of the grid (usually for performance reasons).
- The SetAttribute and DeleteAttribute methods have been added to the PropertyValue class.
- A new PropertyValueAttributesNeeded event has been added (and the related OnPropertyValueAttributesNeeded virtual method) so that custom attributes can be set on a property as soon as its PropertyValue instance has been created.
- The PropertyChanging event has been added. It is triggered just before the target properties are actually updated after the user changed a value in the grid.
- A new ReadOnlyChildProperties attribute enables to force all child properties to be set as readonly.
Bugs fixed:
- A bug in the trackbar inplace control could prevent the trackbar to update the underlying value under certain conditions when RefreshProperties is internally called. An exception could also be raised.
- A realtime AlphaColorPicker could be broken and create a crash if a change of the color by the picker was producing an internal call to RefreshProperties.
- The AlphaColorPicker could not handle multiple values from multiple target instances.
- When creating a property, a TypeConverterAttribute passed as an argument to AppendProperty-like methods was not used while determining its child properties (GetProperties was not called).
- Under Vista, when switching from/to aero theme, all the themed parts in the grid were disappearing.
- There could be a crash when using SelectedObjects and a property was decorated with a MergableProperty attribute set to false.
- A performance issue has been fixed. SelectedObject(s) should be faster to populate the grid especially when there are numerous properties in the grid.
- PropertyDescriptorCollections supplied by TypeConverters or TypeDescriptors could be altered by SPG (during the pre-filtering processing) which is a problem when the client application tries to cache such collections.
- The PropertyGrid.AddTargetInstance (which you can call to add a new target on a manually created property) had a typo/bug preventing to set a common value to a property of multiple target instances.
- If a parent property was set as readonly (by any mean) then the child properties were forced as readonly too. In some cases, this was not correct. It is now enforced only if the parent property has a TypeConverter whose GetCreatetInstanceSupported method returns true.
Changes:
- PropertyValue.SetValueFromInPlaceCtrl() takes a new argument (string valueKey which corresponds to the key of an additional value attached to the property, like the unit in a Unit feel).
- If a property is ReadOnly, it won't continue to force the child properties to be readonly. There was a bad assumption made by SPG about this subject. If you want to force such behavior in your application you can use the new ReadOnlyChildPropertiesAttribute on the parent property.
Version 2.5:
-----------
New features:
- SelectedObjects now allows full edition of immutable properties (the one whose TypeConverter's CreateInstanceSupported returns true) and collections.
- Displayed values (set by PropertyValue.ResetDisplayedValues or by the PropertyValueDisplayedAsAttribute) are more flexible. Before you could only set them as strings. You can now supply objects or pairs