Sorting CategoryAttributes for PropertyGrids

This is my first post, and I just want to say that I am so excited that I found this dev forum. It will come in very handy for development. Thanks everyone for being a part of it.

I wanted to talk about Sorting Categories in property grids. I have failed to find anything that tells me how to do it. I have made a properties sorting class, but not category. I have come across a way to do it. Pardon my stupidity if everyone already knows this, but for the new devs, it will help.
Lets take my example:

This is property grid data to be shown in a windows form property grid.
I'm not going to go into the winform code but you would set your values in the form1_load method (standard name) in your Form1.cs file.


privatevoid Form1_Load(object sender, System.EventArgs e)
{
PropertyGridData data =new PropertyGridData();
data.Type1 = "First Type1";
data.Type2 = "First Type2";
data.Type3 = "First Type3";

propertyGrid1.SelectedObject = data;
}


[DefaultPropertyAttribute("Name")]
publicclass PropertyGridData
{
privatestring _a;
privatestring _b;
privatestring _c;


[CategoryAttribute("A"), DescriptionAttribute("Type1")]
publicstring Type1
{
get
{
return _a;
}

set
{
_a = value;
}
}

[CategoryAttribute("B"), DescriptionAttribute("Type2")]
publicstring Type2
{
get
{
return _b;
}

set
{
_b = value;
}
}

[CategoryAttribute("C"), DescriptionAttribute("Type3")]
publicint Type3
{
get
{
return _c;
}

set
{
_c = value;
}
}
public PropertyGridData()
{
//
// TODO: Add constructor logic here
//
}
}


Now when the property grid is shown after compiling and executing, it will automatically alphabetically arrange the Category names.
The only way I have been able to find out to do a custom arrange is using meta characters in the attribute.

example:

If I want C Category to be shown first in the grid I would use the \r meta character.


[CategoryAttribute("\r\r\rC"), DescriptionAttribute("Type3")]

The more \r characters in the string, the higher up in the heiarchy it will be.


[CategoryAttribute("\r\rC"), DescriptionAttribute("Type3")]
[CategoryAttribute("\rB"), DescriptionAttribute("Type2")]
[CategoryAttribute("A"), DescriptionAttribute("Type1")]

This will give you C, B, then A Categories.

I hope this helps some of you guys that have been looking for information on category propertygrid sorting.

Cheers
- Sipes

[4791 byte] By [MattSipes] at [2008-1-25]
# 1
As I'm a new to C# I can say 'This is nice! This I can use.' Big Smile

Only....
I've tried

[CategoryAttribute("\rSetting"), DescriptionAttribute("bladibla")]

It shows me a <blank> category instead of the 'Setting' I'm expecting.
I'm working with VS2005 (beta2).

And, related to sorting the category's, is there a way to sort the elements within a category?

Coretta at 2007-9-8 > top of Msdn Tech,Windows Forms,Windows Forms Designer...
# 2

Ahhh you want to sort the properties within the categories? muahahahhaha I wrote a class for that:
implement it like this:

Add [TypeConverter(typeof(PropertySorter))] before your class wherever your data is.... and then this is how you call PropertyOrder:


[CategoryAttribute("\r\r\rIdentity"), DescriptionAttribute("Class"), PropertyOrder(2)]

[CategoryAttribute("\r\r\rIdentity"), DescriptionAttribute("Type"), PropertyOrder(1) ]




When you add it as a parameter within your [ ] brackets, call "PropertyOrder" with the lowest number being the first in the list of properties in the category.

It will show up like this

Identity
1. Type
2. Class

in that order.

PropertyOrder code :


using System;
using
System.Collections;
using
System.ComponentModel;

namespace PropertySorter
{
public class PropertySorter : ExpandableObjectConverter
{
#region Methods
public override bool GetPropertiesSupported(ITypeDescriptorContext context)
{
return true;
}

public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
{
//
// This override returns a list of properties in order
//
PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(value, attributes);
ArrayList orderedProperties = new ArrayList();
foreach (PropertyDescriptor pd in pdc)
{
Attribute attribute = pd.Attributes[typeof(PropertyOrderAttribute)];
if (attribute != null)
{
//
// If the attribute is found, then create an pair object to hold it
//
PropertyOrderAttribute poa = (PropertyOrderAttribute)attribute;
orderedProperties.Add(new PropertyOrderPair(pd.Name,poa.Order));
}
else
{
//
// If no order attribute is specifed then given it an order of 0
//
orderedProperties.Add(new PropertyOrderPair(pd.Name,0));
}
}
//
// Perform the actual order using the value PropertyOrderPair classes
// implementation of IComparable to sort
//
orderedProperties.Sort();
//
// Build a string list of the ordered names
//
ArrayList propertyNames = new ArrayList();
foreach (PropertyOrderPair pop in orderedProperties)
{
propertyNames.Add(pop.Name);
}
//
// Pass in the ordered list for the PropertyDescriptorCollection to sort by
//
return pdc.Sort((string[])propertyNames.ToArray(typeof(string)));
}
#endregion
}

#region Helper Class - PropertyOrderAttribute
[AttributeUsage(AttributeTargets.Property)]
public class PropertyOrderAttribute : Attribute
{
//
// Simple attribute to allow the order of a property to be specified
//
private int _order;
public PropertyOrderAttribute(int order)
{
_order = order;
}

public int Order
{
get
{
return _order;
}
}
}
#endregion

#region Helper Class - PropertyOrderPair
public class PropertyOrderPair : IComparable
{
private int _order;
private string _name;
public string Name
{
get
{
return _name;
}
}

public PropertyOrderPair(string name, int order)
{
_order = order;
_name = name;
}

public int CompareTo(object obj)
{
//
// Sort the pair objects by ordering by order value
// Equal values get the same rank
//
int otherOrder = ((PropertyOrderPair)obj)._order;
if (otherOrder == _order)
{
//
// If order not specified, sort by name
//
string otherName = ((PropertyOrderPair)obj)._name;
return string.Compare(_name,otherName);
}
else if (otherOrder > _order)
{
return -1;
}
return 1;
}
}
#endregion
}


Enjoy!

MattSipes at 2007-9-8 > top of Msdn Tech,Windows Forms,Windows Forms Designer...
# 3
I am trying to sort the categories in a property grid as you described. Previously I used \t, but this now displays a square symbol for an unprintable character followed by the text. I found this post and tried \r, however I then get no text at all.

Does \r work for anyone else? June CTP of framework,.

Thanks

DarrenSQLIS at 2007-9-8 > top of Msdn Tech,Windows Forms,Windows Forms Designer...
# 4
Works with the example I gave. Read it.
MattSipes at 2007-9-8 > top of Msdn Tech,Windows Forms,Windows Forms Designer...
# 5

I am only interested in sorting the categories, not the properties in a category. You suggest using \r, but as Coretta also mentioned, this does not work. Do you have it working on a recent build, e.g. June CTP.

DarrenSQLIS at 2007-9-8 > top of Msdn Tech,Windows Forms,Windows Forms Designer...
# 6
I'm using the VSNET with the follow info:
Microsoft Development Environment 2003 Version7 1 3088

Microsoft.NET Framework 1.1 Version1 1 4322 SP1

Copyright 1998 2002 Microsoft Corporation. All rights reserved
The "\r" works like a charm! 10x for the tip!Smile

CFQüeb at 2007-9-8 > top of Msdn Tech,Windows Forms,Windows Forms Designer...
# 7
Well \t worked fine as well in VS 2003, but neither work in VS2005, since about the April CTP. Anyone got a VS2005 solution?
DarrenSQLIS at 2007-9-8 > top of Msdn Tech,Windows Forms,Windows Forms Designer...
# 8
Taking up again this question: someone has resolved how to sort the categories in VSNET 2005?. The \r does not works in this release of VSNET2005 (FINAL). I need sort the categories in my project. I want to say that this tip works fine in VSNET 2003.

Regards

Tabas at 2007-9-8 > top of Msdn Tech,Windows Forms,Windows Forms Designer...
# 9
Has anyone found a way to do this in VS2005? The \t and \r solutions both work in VS2003 but they don't in 2005.
MadDawg2020 at 2007-9-8 > top of Msdn Tech,Windows Forms,Windows Forms Designer...
# 10
I have ran into the same problem in VS2005, does anyone know of a solutions?
Jackson420 at 2007-9-8 > top of Msdn Tech,Windows Forms,Windows Forms Designer...
# 11

This is so cool.

Now I can do both Sorting CategoryAttributes by Matt's code and sorting categories by using '\t'

Maruno at 2007-9-8 > top of Msdn Tech,Windows Forms,Windows Forms Designer...
# 12

Has anybody come up with a way to do this with VS2005 yet?

I've been asked to sort categories in a property grid, and this is the only topic I could find anywhere that discusses it.

Alan4s at 2007-9-8 > top of Msdn Tech,Windows Forms,Windows Forms Designer...
# 13

\t or \r may work for you, but does not work for everyone. The logic is sound, but some combination of settings means that these characters are sometimes hidden, and sometimes displayed as non-printable characters, the small square.

I opened a PSS case, and the response was if it works it works, otherwise there is no better way of doing this as the sorting for the grid is hardcoded, so no way to override or influence it. In my case I always see the square.

DarrenSQLIS at 2007-9-8 > top of Msdn Tech,Windows Forms,Windows Forms Designer...
# 14

I've submitted a feature request (Suggestion) to Microsoft for a way of doing this.

If it's important to you, go to http://lab.msdn.microsoft.com/productfeedback/viewfeedback.aspx?feedbackid=4d30a974-7bfe-4f8d-af5e-39b27306d726 and vote on this feature so it gets some attention.

Alan4s at 2007-9-8 > top of Msdn Tech,Windows Forms,Windows Forms Designer...