This is a migrated thread and some comments may be shown as answers.

[Solved] Simplified Generics Grouping Helpers for Custom Binding

2 Answers 116 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Josh Anderson
Top achievements
Rank 1
Josh Anderson asked on 01 Jul 2011, 01:53 AM

Requirements

RadControls version 2011.1.315
.NET version 4.0
Visual Studio version VS 2010
programming language C#
browser support

all browsers supported by RadControls


PROJECT DESCRIPTION
These helper methods utilize generics and reflection in order to simplify grouping when using custom binding. These are based on other examples provided by Telerik, but simplify usage by allowing you to avoid a series of if/then or switch statements based on the grouped field.  The helper class is as follows:

public static class TelerikGridHelpers
{
    public static IEnumerable<AggregateFunctionsGroup> BuildInnerGroup<T, TObject>(IEnumerable<TObject> group, Func<TObject, T> groupSelector, Func<IEnumerable<TObject>, IEnumerable> innerSelector)
    {
        return group.GroupBy(groupSelector)
                .Select(i => new AggregateFunctionsGroup
                {
                    Key = i.Key,
                    Items = innerSelector(i)
                });
    }
 
    public static Func<IEnumerable<TObject>, IEnumerable<AggregateFunctionsGroup>> BuildGroup<T, TObject>(Func<TObject, T> groupSelector, Func<IEnumerable<TObject>, IEnumerable<AggregateFunctionsGroup>> selectorBuilder)
    {
        var tempSelector = selectorBuilder;
        return g => g.GroupBy(groupSelector)
                     .Select(c => new AggregateFunctionsGroup
                     {
                         Key = c.Key,
                         HasSubgroups = true,
                         Items = tempSelector.Invoke(c).ToList()
                     });
    }
 
    public static IEnumerable<AggregateFunctionsGroup> ApplyGrouping<T>(IQueryable<T> data, IList<GroupDescriptor> groupDescriptors)
    {
        Func<IEnumerable<T>, IEnumerable<AggregateFunctionsGroup>> selector = null;
        foreach (var descriptor in groupDescriptors.Reverse())
        {
            var tempDescriptor = descriptor;
            if (selector == null)
                selector = g => BuildInnerGroup(g.Select(p => p), p => p.GetType().GetProperty(tempDescriptor.Member).GetValue(p, null), i => i.ToList());
            else
                selector = BuildGroup(p => p.GetType().GetProperty(tempDescriptor.Member).GetValue(p, null), selector);
        }
 
        return selector != null
                   ? selector.Invoke(data).ToList()
                   : null;
    }
}

In order to utilize these helpers in a custom binding scenario, you must first ensure that your data source first applies sorting by the fields (in reverse) in the GridCommand.GroupDescriptors argument to the controller action you're calling to get the GridModel.

Once you have your raw IEnumerable of the grid items, you simply need to return the GridModel as follows:

return command.GroupDescriptors.Any()
           ? new GridModel
                 {
                     Data = TelerikGridHelpers.ApplyGrouping(gridItems.AsQueryable(), command.GroupDescriptors),
                     // In my instance this is from my call to an NHibernate repository because I'm doing paging on the DB.
                     Total = (Int32) total.Value
                 }
           : new GridModel {Data = accountDTOs, Total = (Int32) total.Value};

This saves having to put "magic string" tests for the Member value of the group descriptor.

2 Answers, 1 is accepted

Sort by
0
Atanas Korchev
Telerik team
answered on 04 Jul 2011, 09:31 AM
Hi Josh Anderson,

Could you please provide a runnable example? You can check our code library guidelines for a reference.

Greetings,
Atanas Korchev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Luis
Top achievements
Rank 1
answered on 17 Jan 2012, 09:26 PM
Finally I got it!

With the help of the guys on this thread I'm proud to say that I came to a satisfactory result, pluggable in any type of MVC application without much difficulty and almost none in the settings.

I published the project on Bitbucket and Nuget, please take a look and send me some feedbacks.

https://bitbucket.org/Lunadie/telerikmvcgridcustombindinghelper/wiki/Home 

https://nuget.org/packages/TelerikMvcGridCustomBindingHelper   
Tags
General Discussions
Asked by
Josh Anderson
Top achievements
Rank 1
Answers by
Atanas Korchev
Telerik team
Luis
Top achievements
Rank 1
Share this question
or