Inherit DataFactory - Categories?

Grids for WPF Forum

Posted 10 years ago by jeff jarrell
I am implementing a Factory that inherits from DataFactory. I override the method called GetProperties that provides the list of properties. Now the properties need to be assembled into categories.

So there is an override that returns a List of IDataAccessors. Without doing anything, I get the Misc category with all the properties assembled in the Misc(ICategoryDataAccessor). Accessors collection.

It appears that inheriting DataFactory doesn't really support categories or if it does, how does the property get associated with the category? The IPropertyDataAccessor does have a 'string category but it is only a getter, what does this mean. On the ICategoryDataAccessor there isn't much in this interface to make the link.

Taking another tack, I could just implement IDataFactory and provide an implementation for GetDataAccessors, create the categories and then painstaking assemble the properties underneath the proper category using ICategoryDataAccessor.Accessors collection.

It seems like I should be able to provide my collection of categories and then on each property set a reference of some sort to the category and then let the PropertyGrid sort it out. (This is really the main question, where am I off?)

One other question, is there value to inheriting from CachedPropertyDataAccessorBase for the PropertyDataAccessors. These objects are re-created each time on a SelectedObject(s) so I don't know what can be cached.

Appreciate any comments.

Thanks, jeff

Comments (4)

Posted 10 years ago by Actipro Software Support - Cleveland, OH, USA
There are actually tree methods you can overload:

1. GetProperties(object, ...) - Should return a list of IPropertyDataAccessor objects, one for each property on the specified object
2. GetProperties(object[], ...) - Should return a list of IPropertyDataAccessor objects, one for each property that is common to all the specified objects
3. GetDataAccessors(object[], ...) - Should return a list of IDataAccessor objects (e.g. IPropertyDataAccesor, ICategoryDataAccessor), which can be just properties or categories with properties, or several level of categories.

You can choose to override at any level, and which one depends on your needs.

The first (#1) allows you customize the properties exposed by an object. You must implement this if deriving from DataFactory, but not if you are simply extending TypeDescriptorFactory or TypeReflectionFactory.

The second (#2) allows you to customize how common properties (returned from calling #1 for each object) are "merged". This is used when the PropertyGrid.SelectedObjects property is set to more than 1 object.

The third (#3) allows you to customize how the properties returned from calling #2 are "organized". The default implementation reads the IPropertyDataAccessor.Category property to get the category, and uses the specified options to determine if and how categorization is performed.

Your list of "categories" would really just be returned from the IPropertyDataAccessor.Category property. But if you override #3 you can perform this anyway you want.

Eventhough the properties are recreated when the SelectedObject(s) is changed, their property values can be queried several times for display purposes. For example, it pulls the Description when the property is selected and the summary area is visible. Instead of going back to the TypeDescriptor or reflection, the CachedPropertyDataAccessorBase will cache it. But it's really up to you ;-)

Actipro Software Support

Posted 10 years ago by jeff jarrell
Thank you for the prompt response. Before I go off to experiment a little more I have a quick question.

In #3 you say the default implementation IPropertyDataAccessor.Category property is used to get the category. This is string. When I try it, that string becomes the display string. How does it become a key to the ICategoryDataAccessor? Our properties are nested so that we do need the ICategoryDataAccessors with properties grouped under them.

It would seem like the IPropertyDataAccessor would have reference to the ICategoryDataAccessor. When I look at the ICategoryDataAccessor there isn't much there. Only a DisplayName, nothing much to bind the string from the IPropertyDataAccessor.

Posted 10 years ago by Actipro Software Support - Cleveland, OH, USA
The list of properties each has a Category, which as you said becomes it's display name. So the default implementation will iterate over the properties, get it's category, create an instance of CategoryDataAccessor for that category (if it has not already been created), then adds the property to the Accessors property of that CategoryDataAccessor.

So the properties are used to construct the categories. Then the categories hold one or more properties in the Accessors collection. If a property doesn't specify a category, then it's put in the Misc category (assuming categorization is on). A IPropertyDataAccessor does not have a reference to the ICategoryDataAccessor that it belongs to.

If you need to include additional levels of categories, then you can simply add a CategoryDataAccessor to the Accessors collection of another CategoryDataAccessor, then add properties where you need them.

If you require that the IPropertyDataAccessor has a reference back to it's ICategoryDataAccessor, then you would need to create your own classes for that (and use them in #1 and #3 above (maybe #2 if merging too). You can also derive from PropertyDataAccessor and/or CategoryDataAccessor, to save time.

Actipro Software Support

Posted 10 years ago by jeff jarrell
Ok. This is helpful. Thank you.

The latest build of this product (v2018.1 build 0675) was released 9 days ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.