UXPropertyGrid is an advanced editor control which provides an easy way to dynamically handle a vary types of objects instead of writing a custom view for each type. Designed to display a large number of properties, UXPropertyGrid implements VirtualizingStackPanel to solve the performance issue which may occur when dealing with large objects. UXPropertyGrid also comes with customizable editors which makes it possible to fit in various user specific scenarios. To improve its performance, UXPropertyGrid also will reuse the existing editors for different properties that use the same editor type to avoid object creation overhead.
It's easy to use UXPropertyGrid control, you just need to provide the object's information and UXPropertyGrid will automatically generate and display the object properties in UXPropertyGrid. At runtime, the properties can be switched to be displayed in alphabetical or in a categorized mode. UXPropertyGrid also provide the capability to filter properties by performing query through the built-in search box.
The following shows how properties is displayed in alphabetical and categorized mode.
UXPropertyGrid allows you to bind a collection of objects into SelectedObjects property. The objects can be in the same type or in a different type. Of course, UXPropertyGrid only will display the intersecting properties from each objects.
Using Properties Source
UXPropertyGrid also allows you to directly provide the property definition of properties you would like to show, so UXPropertyGrid doesn't need to generate the given object's properties. The following example shows how to use PropertiesSource in UXPropertyGrid.
In general, there are three ways to define how UXPropertyGrid generate the object's properties. You can have UXPropertyGrid generating all properties or restrict only specific properties to be displayed, which can be set through PropertyListMode property. There are three mode that you can choose.
All public properties from the given object will be generated.
All public properties which marked with PropertyMember attribute will be generated.
All public properties which marked with PropertyMember and DataMember attribute will be generated.
PropertyMember attribute have several member that can be used to customize the displayed properties, such as:
If specified, UXPropertyGrid will display it as the property name. Otherwise the marked property name will be used.
Used to define the category of the marked property. If not specified, UXPropertyGrid will look into DefaultCategoryName property. If not specified, then the property will be grouped into Others category.
If specified, UXPropertyGrid will display it as the property description.
If specified, UXPropertyGrid will use this value when performing reset action.
The following example shows how to decorate property with PropertyMember attribute.
By default, UXPropertyGrid will regenerate the properties when the given objects is changed. This will cause performance issue if the number of properties which need to be generated is relatively large. When the caching feature is enabled, UXPropertyGrid only will generate properties for each object type once to achieve a better performance and more responsive results. To enable this feature, simply set EnableCaching property to True.
Customizing Displayed Property Value
UXPropertyGrid provides several ways to customize the displayed property value.
UXPropertyGrid allows you to format the displayed property value using StringFormat, which is exposed by PropertyMember attribute. If not specified, the property value will be displayed using the default format (ToString). The following code shows how to specify StringFormat in PropertyMember attribute.
UXPropertyGrid provides a capability to customize the displayed property value via DataListProvider. Each data list provider must be inherited from EditorDataProvider class. EditorDataProvider exposes some unimplemented methods, which allow you to implement your own logic to provide the displayed data. To use this feature, you need to decorate your property with DataListProvider attribute. You also need to pass the data list provider into this attribute, either using strongly-typed or weakly-typed overload.
The following code shows how to specify DataListProvider using strongly-typed.
The following code shows how to specify DataListProvider using weakly-typed. Make sure that the type name is fully qualified when using the weakly-typed overload.
By default, the provide data operation will be executed in synchronous way. But in some cases, suppose you need to perform a long running process, you will need to run it asynchronously to give a better experience for the user. To run it asynchronously, set the IsAsync property to True.
To perform a synchronous operation, you must implement GetSingle method to provide the new data that will be displayed. A property definition will be passed to this method as a parameter.
To learn more about synchronous DataListProvider, you can refer to How To Implement Synchronous DataListProvider in UXPropertyGrid.
To perform an asynchronous operation, you must implement BeginSingleAsync method. After the asynchronous operation is completed, you need to notify it by calling EndGetSingleAsync method and passing the new data that will be displayed.
To learn more about asynchronous DataListProvider, you can refer to How To Implement Asynchronous DataListProvider in UXPropertyGrid.
Customizing UXPropertyGrid Editor
To support a variety of user scenarios, UXPropertyGrid comes with eight built-in editors as follows.
Default editor is defined to use UXTextBox control to host the property value. All properties with string type and the others which is not applicable with the other editor types, will be defined to use this editor type. To customize the default editor's appearance, you can use DefaultEditorStyle and DefaultEditorTemplate property.
Numeric editor is defined to use UXCurrencyEditor control to host the property value. All numeric properties will use this editor type. To customize the numeric editor's appearance, you can use NumericEditorStyle and NumericEditorTemplate property.
DateTime editor is defined to use UXDateTimePicker control to host the property value. All datetime properties will use this editor type. To customize the datetime editor's appearance, you can use DateTimeEditorStyle and DateTimeEditorTemplate property.
All boolean properties will be use boolean editor. By default, this editor type is defined to use UXComboBox control, enables it to perform selection between True and False. To customize the boolean editor's appearance, you can use BooleanEditorStyle and BooleanEditorTemplate property.
Enum editor will be used by all enum properties. Same as boolean editor, enum editor also use UXComboBox control to host the enum values. To customize the enum editor's appearance, you can use EnumEditorStyle and EnumEditorTemplate property.
Items editor will be used if the property is specified to use DataListProvider. Of course, items editor will use UXComboBox control to serve the data. To provide the data, you need to use DataListProvider, which is not only used to customize the displayed property value. Same with the one which has been explained in previous section, you need to decide whether will use synchronous or asynchronous operation.
To perform a synchronous operation, you need to implement GetData method to provide the data.
To perform an asynchronous operation, you need to implement BeginGetDataAsync method. After the asynchronous operation is completed, you need to notify it by calling EndGetDataAsync method and passing the retrieved data to it.
Besides that, you also need to specify DisplayMemberPath and SelectedValuePath for the items editor. To customize the items editor's appearance, you can use ItemsEditorStyle and ItemsEditorTemplate property. To learn more about DataListProvider, you can refer to How To Implement Synchronous DataListProvider in UXPropertyGrid or How To Implement Asynchronous DataListProvider in UXPropertyGrid.
Collection editor will be used if a property is referred as a collection. By default, collection editor will use UXPropertyGridCollectionEditor control, which has the capability to add, delete, and move items. Furthermore, UXPropertyGrid also provides several command-related properties that you can bind to your ViewModel to execute a method depending on the actions. These command-related properties are listed as follows.
Called when you add new items to the collection.
Called when you delete items from the collection.
Called when you move the collection items up.
Called when you move the collection items down.
When invoked, all of these commands will pass CollectionItemsCommandArgs as an argument which contains information about the corresponding items. In addition, if you want to cancel these action, simply set the argument's Cancel property to True.
Custom editor is designed to be used by a complex object. By default, custom editor will use UXPropertyGridCustomEditor control to host the object. To customize the custom editor's appearance, you can use CustomEditorStyle and CustomEditorTemplate property.
Another approach to customize editor is via EditorType. This approach is only suitable to be used when you need to apply a custom user control as an editor on a specific property. EditorType can be set through PropertyMember attribute.
Besides that, you also can specify it using weakly-typed as follows.
In some case, you would need to apply different style for the specific property type or based on property name. To fulfill this need, you can use EditorDefinitions.
A rather unique scenario is where you would like to apply different style that depends on the property definitions. This can be achieved elegantly in UXPropertyGrid by using EditorSelector, which will be explained in the following code.
Not only to customize editor style, EditorSelector also enables you to customize editor template, which works similarly to any other template selectors.
Keyboard Support in UXPropertyGrid
At a glance, the following illustration will shows how to use keyboard to navigate through UXPropertyGrid.