How can I customize category sorting on a PropertyGrid?
Asked Answered
H

5

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?

Habana answered 5/5, 2009 at 4:21 Comment(1)
Take a look at this article CodeProject: Ordering Items in the Property Grid.Aceto
P
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).

Pleading answered 5/5, 2009 at 7:10 Comment(0)
R
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...

Roulade answered 15/6, 2009 at 10:43 Comment(5)
The final trick in that is pure evil genius ;-p Nasty, but if it gets the job done....Pleading
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.Nether
The problem with the tooltip is minor compared with the benefits of being able to do this. Nice find.Pendergast
Take a look at this article too. CodeProject: Ordering Items in the Property Grid.Aceto
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. :-)Chester
D
21

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.

Detritus answered 29/1, 2014 at 20:26 Comment(6)
Instead of \t, \u200B could be convenient, it is an empty character (no-space)Fusty
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?Seif
@FabriceT \u200B doesn't work for me. It is not visible in the control, but doesn't affect the order either.Seif
use \r instead to avoid tooltip issue.Calciferol
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.Fusty
Tried \u200B in Framework 4.7. Doesn't preserve the order.Grozny
P
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).

Pleading answered 5/5, 2009 at 7:10 Comment(0)
G
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.

Grenade answered 4/6, 2015 at 15:2 Comment(1)
\r adds new lines on both the PropertyGrid control and the tooltipSeif
S
1

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.

Seif answered 15/6, 2021 at 14:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.