So I have a CategoryAttribute
class:
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Method, AllowMultiple = false)]
public class CategoryAttribute : PropertyAttribute
{
public readonly string name;
public readonly float order;
public CategoryAttribute(string name, float order)
{
this.name = name;
this.order = order;
}
}
That way I can categorize my class members to draw in the inspector (Unity3D) in groups, like so:
Now these are the default groups ("Fields" with an order of 0, "Properties" with an order of 1 and "Methods" with an order of 2).
Now I want to let users to create their own categories with their own names and orders, so say I wanted to create a "Debug" category:
[Category("Debug", 3)]
public bool debugMode;
[Category("Debug", 3)]
public bool drawGizmos;
[Category("Debug", 3)]
public Color gizmosColor;
Now both these three fields will be drawn in a category called "Debug" after "Methods" (cause it has a higher order) (I know the syntax is repetitive, I'll do something about it later...)
Now I can't seem to group my members by the category name, and order those groups by that category order number, I tried but bumped:
var members = fields.Concat<MemberInfo>(properties).Concat(methods);
var userCategories = from m in members
let cat = m.GetCustomAttributes(typeof(CategoryAttribute), false)[0]
where attr != null
let cat = attr as CategoryAttribute
group m by cat.name into g
orderby cat.order // bump!
And:
var userCategories = members.Select(m => new {m, cat = m.GetCustomAttributes(typeof(CategoryAttribute), false)[0] as CategoryAttribute})
.Where(x => x.cat != null)
.GroupBy(x => x.cat.name)
.OrderBy(x => x.cat.order) // duh!
Now I can fiddle around with projections and eventually figure it out, but it might not be the best so I thought maybe someone could help me do this the right way.
Again, I want to group my members by the category name, and order the groups by the category number.
Thank you!
If this is in LINQ to Objects, you could just use:
.OrderBy(g => x.First().cat.order)
Alternatively, you could group by both the name and the order, then use the order part of the key:
.GroupBy(x => new { x.cat.name, x.cat.order })
.OrderBy(g => g.Key.order)
Basically, you need to understand that after the GroupBy
you don't have an individual item which you can ask for the category - you have a group of items. So you need to ask how you would order that group compared with another group.
See more on this question at Stackoverflow