23

How can I customize the sorting of categories in a PropertyGrid?

If I set either of the following...

propertyGrid.PropertySort = PropertySort.Categorized;
propertyGrid.PropertySort = PropertySort.CategorizedAlphabetical;

... then the categories will be alphabetized. ("Alphabetical" would seem to apply to the properties within each category.) If I use PropertySort.NoSort, I lose categorization.

I'm populating my PropertyGrid with SelectObject, which is pretty easy:

this.propertyGrid1.SelectedObject = options;

options is an instance of a class with suitably decorated properties:

    [CategoryAttribute("Category Title"),
    DisplayName("Property Name"),
    Browsable(true),
    ReadOnly(false),
    BindableAttribute(true),
    DesignOnly(false),
    DescriptionAttribute("...")]
    public bool PropertyName {
        get {
            // ...
        }

        set {
            // ...
            this.OnPropertyChanged("PropertyName");
        }
    }

I have a few dozen properties in half a dozen categories.

Is there some way I can adjust the category sort order while preserving my ease of use with SelectedObject?

Garth Kidd
  • 7,264
  • 5
  • 35
  • 36
  • Take a look at this article [CodeProject: Ordering Items in the Property Grid](http://www.codeproject.com/Articles/6611/Ordering-Items-in-the-Property-Grid). – Alex Essilfie Aug 17 '13 at 18:47

5 Answers5

22

I think this link is useful http://bytes.com/groups/net-c/214456-q-ordering-sorting-category-text-propertygrid

I don't believe there is a way to do this. The only thing that I could find that indicates you might be able to do this is the PropertySort property. If you set it to none, it says that the properties are displayed in the order that they are received from the type descriptor. You might be able to create a proxy type descriptor between your object and the propertygrid, which would then return not only the properties in the correct order, but the properties with the categories in the order that you want them in...

gnat
  • 6,213
  • 108
  • 53
  • 73
  • 9
    The final trick in that is pure evil genius ;-p Nasty, but if it gets the job done.... – Marc Gravell Jun 15 '09 at 10:50
  • 1
    Excellent trick. But I found that although \t is removed from the visual display and does allow you to control sorting, it confuses the auto tooltip for the PropertyGrid so that it sometimes thinks it doesn't have the full space to show the property name when it actually does. To make matters worse, the tool tip preserves the \t - so you gets lots of white space when it appears. – bsegraves Mar 30 '12 at 14:39
  • 2
    The problem with the tooltip is minor compared with the benefits of being able to do this. Nice find. – 0E322070 Jul 10 '12 at 10:11
  • Take a look at this article too. [CodeProject: Ordering Items in the Property Grid](http://www.codeproject.com/Articles/6611/Ordering-Items-in-the-Property-Grid). – Alex Essilfie Aug 17 '13 at 18:47
  • 5
    I don't know if you guys saw @JoelB's answer (below), but it's basically this one but on steroids. Much less hacky as far as usage and maintainability goes though. :-) – BrainSlugs83 Feb 04 '14 at 03:10
20

Like @Marc Gravel said in his answer, there's nothing in the framework that allows this behaviour. Any solution will be a hack. With that said, you can use the solution suggested by @Shahab in his answer as a work-around but that doesn't really indicate your intention to anyone maintaining your code. So I think the best you can do is create a custom Attribute which inherits from CategoryAttribute to handle the process for you:

public class CustomSortedCategoryAttribute : CategoryAttribute
{
    private const char NonPrintableChar = '\t';

    public CustomSortedCategoryAttribute(   string category,
                                            ushort categoryPos,
                                            ushort totalCategories)
        : base(category.PadLeft(category.Length + (totalCategories - categoryPos),
                    CustomSortedCategoryAttribute.NonPrintableChar))
    {
    }
}

Then you can use it as such

[CustomSortedCategory("Z Category",1,2)]
public string ZProperty {set;get;}
[CustomSortedCategory("A Category",2,2)]
public string AProperty {set;get;}

Just make sure you set the PropertyGrid's UseCompatibletextRendering property to true to strip out the non-printable characters for you and the PropertySort set to Categorized or CategorizedAlphabetical and you should be good to go.

Community
  • 1
  • 1
Joel B
  • 12,082
  • 10
  • 61
  • 69
  • Instead of `\t`, `\u200B` could be convenient, it is an empty character (no-space) – Fabrice T Apr 06 '21 at 22:55
  • I don't understand why the PropertyGrid control would care about a new made up attribute... What is telling the PropertyGrid that this attribute exists and it should be used for sorting? – stenci Jun 15 '21 at 13:42
  • @FabriceT \u200B doesn't work for me. It is not visible in the control, but doesn't affect the order either. – stenci Jun 15 '21 at 14:10
  • use `\r` instead to avoid tooltip issue. – Ray Jul 06 '21 at 15:36
  • First we are in C#. Or you copy the invisible character. @Raimon I verified it doesn't appear in tooltip. @Stensi it is a Unicode char `\r` is Windows specific **new line** charaxter which won't be useful in .Net Core nor .Net Standard ... I think so.. instead it is better and safe to use unicode characters. – Fabrice T Nov 20 '21 at 05:22
4

A small variation on the '\t' trick described above, I just tried it with carriage return characters ('\r') instead. It seems to work and avoids the tooltip problem caused by the extra space introduced by a tab.

Chris Kessell
  • 71
  • 1
  • 5
4

If you mean that you want the categories sorted in a specific (non-alphabetical) way, then no - I don't think you can do that. You might want to try VisualHint - I expect it does have this (since you can seize a lot more control).

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
0

All the other answers address how to customize the sorting order, but don't address the problem that arises when the user clicks on the Categorized or Alphabetical buttons.

Clicking on those buttons assigns the CategorizedAlphabetical or Alphabetical values to the PropertySort property, while usually (at least for me) the desired behavior would be for them to assign the Categorized or Alphabetical values.

By adding the event PropertySortChanged it is possible to get the correct behavior:

private void propertyGrid1_PropertySortChanged(object sender, EventArgs e)
{
    if (propertyGrid1.PropertySort == PropertySort.CategorizedAlphabetical)
        propertyGrid1.PropertySort = PropertySort.Categorized;
}

By using this event I don't see the problem with the tooltip, because I put the \t only in front of the category names, not in front of the property names.

stenci
  • 8,290
  • 14
  • 64
  • 104