Controling Order of Properties Returned in PropertyDescriptionCollectionControling Order of Properties Returned in PropertyDescriptionCollection
Old forum URL: forums.lhotka.net/forums/t/3661.aspx
Biceman posted on Sunday, October 07, 2007
I'm developing an application using DevExpress grids. Each time I associated a grid with one of my business object lists, the column collection created by the grid was in some seeming random order. I would then have to go through and manually fix the order to something more reasonable (e.g., column order in my SQL table that I have memorized).
After doing some research, I (finally) came across an article Oliver Strum posted a couple of years ago which gave a C# example on how you can overcome this problem using custom property descriptors.
The summarized steps are:
- create a custom attribute which allows you to designate an explicit sort sequence number for each property,
- subclass the PropertyDescriptor class to include a Sort Sequence Number property,
- create a helper class which makes use of the above two items, and
- implement the ITypedList interface for your business object lists
I took his C# code and converted it to VB and made a few minor modifications, namely I added a subsort such that if the Sort Sequence Number values are equal, the Property's Name breaks the tie.
As a result, my grid's column order now defaults to MY desired order. My system has ~100 tables so this made the initial grid design much quicker.
You can do as little as implementing the ITypedList interface (i.e., not apply the custom attribute to any of your properties) and you'll get your properties returned in alphabetical order (which is at least predictable!) The sort sequence number for each Property without the attribute will default to Int32.Max. Since the sort sequence numbers will all be the same, the "break the tie by Property Name" condition will kick-in.
The ITypedList is simple and consists of:
Public Function GetItemProperties(ByVal listAccessors() As PropertyDescriptor) As PropertyDescriptorCollection Implements ITypedList.GetItemProperties
Return SortedPropertyDescriptorCollectionHelper.GetPropertyCollection(GetType(<ListItem ComponentType>))
End Function
where <ListItemComponentType> is the "C" parameter in the "Inherits BusinessListBase(Of T, C)"
Public Function GetListName(ByVal listAccessors() As PropertyDescriptor) As String Implements ITypedList.GetListName
Return Me.GetType.Name
End Function
Note that the listAccessors parameter is ignored currently. For my use this was not an issue and I believe that's the way Oliver had it in his example.
Also, I noticed today when I was upgraded to v3.02 of the framework a method in the Utilities module called GetChildItemType. This takes the type of a list/collection as input and outputs the type of the child item. Using this function would allow the GetType(<ListItem ComponentType>) code to become generic for each list.
The helper function is Shared/Singleton in nature. It caches each Property Descriptor Collection it creates to speed processing for repeated calls.
Figured I would offer it up to other folks that might find it helpful.
Copyright (c) Marimer LLC