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
As I'm a new to C# I can say 'This is nice! This I can use.'
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?
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!
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
Works with the example I gave. Read it.
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.
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!
Well
\t worked fine as well in VS 2003, but neither work in VS2005, since about the April CTP. Anyone got a VS2005 solution?
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
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.
I have ran into the same problem in VS2005, does anyone know of a solutions?
This is so cool.
Now I can do both Sorting CategoryAttributes by Matt's code and sorting categories by using '\t'
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.
\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.