Hi,
I have a collection of points that I display in the property grid using a custom PointCollection class that implements the ICustomTypeDescriptor interface. This is the same way as the samples browser implements corresponding functionality. The PointCollection class adds the individual points to the properties' list in a standard way as follows, with the source collection index as an input:
public PropertyDescriptorCollection GetProperties(){ var pds = new PropertyDescriptorCollection(null); for (int i = 0; i < this.Count; i++) { pds.Add(new PointCollectionDescriptor(this, i)); } return pds;}
The PointCollectionDescriptor constructor looks more or less like this:
public PointCollectionDescriptor(PointCollection col, int idx) : base("#" + (idx + 1), null){ this.collection = col; ...
}
The output in the property grid is given in the attached image. As we can see from the image, the individual points seem to be sorted by name by the property grid, even though they are added in proper order in the PropertyDescriptorCollection. Item '#10' should be at the bottom of the list, not as item 2.
How can I get the sort order correct?
I have tried to fix this by overriding the PropertyDescriptorCollection class with an implementation that implements the various sorting methods, and tried using this class instead in the code snippet above. However, when I do this the sorting methods are never called by the property grid!
Regards,Leif
Hello and thank you for posting!
I have been looking into your description and the provided code snippets and I am not sure what might go wrong with the custom comparer that you are using. Would it be possible to share the comparer code or a sample application so I can investigate it for you? Thank you in advance.
attached is a sample application that basically do the same as my main application. The 'PropertyOwner' class has a '#define USE_MY_SORT' directive that is used to enable use of a custom PropertyDescriptorCollection, 'NoneSortingPropertyDescriptorCollection', that should do the sorting. When setting breakpoints in this class' various sorting methods I find that they are never called.
Hello Leif,
Thank you for the provided sample project. The Sorting methods are not called for the MyCollectionDescriptor object in order the sorting to be applied (e.g. pds.Sort())You can use the PropertySOrtComparer to set a custom sorting. In the snippet below it Compare method just returns 1 so that the elements in the collection are not moved:…propertyGrid.SelectedObject = Property; propertyGrid.PropertySortComparer = new MyCustomPropertyComparer(); }
public PropertyOwner Property { get; } = new PropertyOwner(); } public class MyCustomPropertyComparer : IComparer<PropertyGridPropertyItem> { public int Compare(PropertyGridPropertyItem x, PropertyGridPropertyItem y) { // provide your custom comparing/sorting logic here return 1; } }
This may work (and do work for the simple attached sample), but as it requires a reference to the XamPropertyGrid itself it will generate a lot of ugly code to be useful in my main, more advanced application.
The different properties displayed in the property grid will be of different types that will require different comparers. The property objects to be displayed in the grid do not (and should not) reference any UI elements directly (the PropertyOwner class in my attached sample doesn't reference the property grid either). My MVVM based application e.g. sets up the 'SelectedObjects' property of the XamPropertyGrid through data binding and even this pattern can't be extended to set up the PropertySortComparer since this property isn't a Dependency Property.
Thanks for the new suggestion. I will investigate which of the options I will go for. At least the issue is solvable.
Hi Lief -
If it is not possible/convenient for you to implement the provided solution with a single PropertyGridPropertyItem comparer that has custom compare logic for the various data types you are expecting then there is another workaround you can try. If you want to preserve the order of the properties in the PropertyDescriptorCollection (i.e., if you have added the PropertyDescriptors to the PropertyDescriptorCollection in the desired order), then you can set a custom sort comparer via the XamPropertyGrid.PropertySortComparer property which simply returns 0 from the Compare method like so:
public class MyCustomPropertyComparer : IComparer<PropertyGridPropertyItem>{ public int Compare(PropertyGridPropertyItem x, PropertyGridPropertyItem y) { return 0; }}
This should preserve the order of the items in the PropertyDescriptorCollection.
BTW, in looking into this issue I noticed that the Window Forms property grid provides a programmatic way to bypass sorting by setting its PropertySort property to 'NoSort' (interestingly the control does not provide a way to accomplish this via its UI). With this in mind, an easier/built-in solution to address your scenario would be for us to add a similar capability to the XamPropertyGrid. Since the control currently exposes its sorting/categorizing functionality via a single 'IsCategorized' property, we may have to deprecate that in favor of a property of an enumerated type {'NoSort', 'Alphabetical', 'Categorized', 'CategorizedAlphabetical'} in order to achieve that. You can submit a feature request for this if you would like to see this implemented.
Hope this helps.
Joe