# SumFunction that sums based on another column value

13 posts, 0 answers
1. ##### Paolo
426 posts
Member since:
Jun 2009

Posted 16 Jan 2012 Link to this post

Hello,
in a RadGridView I've some rows that have a field value D and other B, I need to show in the ColunFooter a

Total D :
Total B:

and in another column

Total D value (€)
Total B value (€)

I've tried myself creating a sumfunction but I don't know if I've to create two different (1 for B and 1 for D) or what... can you please provide me a sample?

Thanks
2. ##### Paolo
426 posts
Member since:
Jun 2009

Posted 17 Jan 2012 Link to this post

just an example on how to override default SumFunction class would be ok...
Thanks
3. ##### Dimitrina
Admin
3769 posts

Posted 17 Jan 2012 Link to this post

Hello,

You could use the SourceField property for the sum function. It sets the name of the field which value is used as the argument of the aggregate function.

Greetings,
Didie
the Telerik team
Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>
4. ##### Paolo
426 posts
Member since:
Jun 2009

Posted 17 Jan 2012 Link to this post

Hello Didie,
consider this simple case

D 200
B 90
B 23
D 9

I wish to have

Total D 209
Total B 103

using the sourcefield how do I discriminate if it's a D or B?

5. ##### Dimitrina
Admin
3769 posts

Posted 17 Jan 2012 Link to this post

Hello Paolo,

Then please check this online demo. Following it, you could calculate the values in the column as you wish.

Kind regards,
Didie
the Telerik team
Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>
6. ##### Paolo
426 posts
Member since:
Jun 2009

Posted 17 Jan 2012 Link to this post

Hello Didie,
I got an exception

No generic method 'MarginElaborationSumFunction' on type 'my.Modules.Core.Framework.Aggregates.TestClass' is compatible with the supplied type arguments and arguments. No type arguments should be provided if the method is non-generic.
public class MarginElaborationSumFunction: Telerik.Windows.Data.SumFunction
{

protected override string AggregateMethodName
{
get { return "MarginElaborationSumFunction"; }
}

protected override Type ExtensionMethodsType
{
get
{
return typeof(TestClass);
}
}
}

and the class (for testing I used the same code of the demo)

public static class TestClass
{
public static double MarginElaborationSumFunction<TSource>(IEnumerable<TSource> source, Func<TSource, double> selector)
{
int itemCount = source.Count();
if (itemCount > 1)
{
IEnumerable<double> values = from i in source select Convert.ToDouble(selector(i));

double sum = SumAvg(values);

return Math.Sqrt(sum / (itemCount - 1));
}

return 0;
}

private static double SumAvg(IEnumerable<double> values)
{
double average = values.Average();
double sum = 0;

foreach (double item in values)
{
sum += Math.Pow(item - average, 2);
}

return sum;
}

}

I've tried ingherits from EnumerableSelectorAggregateFunction as well...same result..

Thanks
Paolo
7. ##### Paolo
426 posts
Member since:
Jun 2009

Posted 17 Jan 2012 Link to this post

It's possible that those aggregate won't worki fine with Ideablade's devforce?
8. ##### Paolo
426 posts
Member since:
Jun 2009

Posted 18 Jan 2012 Link to this post

Any help on this?
9. ##### Dimitrina
Admin
3769 posts

Posted 18 Jan 2012 Link to this post

Hello,

Then you could try to create a general aggregate function like so:

var aggregate = new AggregateFunction<Player, int>()
{
AggregationExpression = players =>
players.Where(player => player.ToString().StartsWith("B")).Select(x => x.Number).Sum(),
Caption = "Total B"

};

In the code snippet, the "Player" is the type of the DataContext of the row, "int" is the type of the returned sum.

Kind regards,
Didie
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

10. ##### Paolo
426 posts
Member since:
Jun 2009

Posted 19 Jan 2012 Link to this post

Hello Didie,
where should I put this code? in my custom aggregator?
11. ##### Dimitrina
Admin
3769 posts

Posted 19 Jan 2012 Link to this post

Hi Paolo,

You should add this aggregate function to the AggregateFunctions collection of the column.
For example:

playersGrid.Columns[0].AggregateFunctions.Add(aggregate);

Regards,
Didie
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

12. ##### guga
12 posts
Member since:
Mar 2012

Posted 14 Sep 2012 Link to this post

Hi all, I am having another issue trying to make the aggregate function works.

Here is my agregate function

var aggregate = new AggregateFunction<CrossTabWrapperItem, double?>()
{

AggregationExpression = sum =>
sum.Select(x => x[GetColumnKey(dependencyObject, source)] as double?).Sum(),
ResultFormatString = "{0:n2}"

};

The problem is that the source binding object is CrossTabWrapperItem<Movie, CountryMovieValues> which base class is CrossTabWrapperItem. So when I ran this aggregate function I got the following error

Expression of type 'System.Linq.IGrouping`2[System.Int32,SilverlightApplication1.CrossTabWrapperItem`2[SilverlightApplication1.Movie,SilverlightApplication1.CountryMovieValues]]' cannot be used for parameter of type 'System.Collections.Generic.IEnumerable`1[SilverlightApplication1.CrossTabWrapperItem]' of method 'System.Collections.Generic.IEnumerable`1[System.Nullable`1[System.Double]] Select[CrossTabWrapperItem,Nullable`1](System.Collections.Generic.IEnumerable`1[SilverlightApplication1.CrossTabWrapperItem], System.Func`2[SilverlightApplication1.CrossTabWrapperItem,System.Nullable`1[System.Double]])'

I know that if I use the aggregate like this (see next line) will work but I need to make this generic, so I can use it in all my implementations
var aggregate = new AggregateFunction<CrossTabWrapperItem<Movie, CountryMovieValues>, double?>()....

Anyone know how can I achieve this behaviour?

Thanks.
13. ##### MiddleTommy
163 posts
Member since:
Nov 2009

Posted 19 Feb 2013 Link to this post

I am having the same issue with a custom Aggregate.
Any help on what has Broken would be helpful

private static void AddAggregateFunction(GridViewColumn column)
{

AggregateFunction<ISize, string> mySumfunction = new AggregateFunction<ISize, string>();

mySumfunction.AggregationExpression = items => Length.New(items.Sum(i=> i.quan * i.length)).ToString();

column.AggregateFunctions.Add(mySumfunction);
}

Expression of type 'System.Linq.IGrouping`2[System.Int32,SilverCards.Web.Model.part]' cannot be used for parameter of type 'System.Collections.Generic.IEnumerable`1[SilverCards.Web.Model.ISize]' of method 'Int32 Sum[ISize](System.Collections.Generic.IEnumerable`1[SilverCards.Web.Model.ISize], System.Func`2[SilverCards.Web.Model.ISize,System.Int32])' ---> System.ArgumentException: Expression of type 'System.Linq.IGrouping`2[System.Int32,SilverCards.Web.Model.part]' cannot be used for parameter of type 'System.Collections.Generic.IEnumerable`1[SilverCards.Web.Model.ISize]' of method 'Int32 Sum[ISize](System.Collections.Generic.IEnumerable`1[SilverCards.Web.Model.ISize], System.Func`2[SilverCards.Web.Model.ISize,System.Int32])'
at System.Linq.Expressions.Expression.ValidateOneArgument(MethodBase method, ExpressionType nodeKind, Expression arg, ParameterInfo pi)
at System.Linq.Expressions.Expression.ValidateArgumentTypes(MethodBase method, ExpressionType nodeKind, ReadOnlyCollection`1& arguments)
at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, IEnumerable`1 arguments)
at System.Linq.Expressions.MethodCallExpressionN.Rewrite(Expression instance, IList`1 args)
at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at System.Linq.Expressions.ExpressionVisitor.VisitUnary(UnaryExpression node)
at System.Linq.Expressions.UnaryExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at System.Linq.Expressions.ExpressionVisitor.VisitArguments(IArgumentProvider nodes)
at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at Telerik.Windows.Data.Expressions.ParameterRewriter.Rewrite(LambdaExpression lambda, ParameterExpression newParameter)
at Telerik.Windows.Data.AggregateFunction`2.CreateAggregateExpression(Expression enumerableExpression)
at Telerik.Windows.Data.Expressions.GroupDescriptorExpressionBuilder.<ProjectionPropertyValueExpressions>b__3(AggregateFunction f)
at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Telerik.Windows.Data.Expressions.GroupDescriptorExpressionBuilder.CreateProjectionInitExpression()
at Telerik.Windows.Data.Expressions.GroupDescriptorExpressionBuilder.CreateAggregateFunctionsProjectionMemberBinding()
at Telerik.Windows.Data.Expressions.GroupDescriptorExpressionBuilder.<CreateMemberBindings>d__0.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Dynamic.Utils.CollectionExtensions.ToReadOnly[T](IEnumerable`1 enumerable)
at System.Linq.Expressions.Expression.MemberInit(NewExpression newExpression, IEnumerable`1 bindings)
at Telerik.Windows.Data.Expressions.GroupDescriptorExpressionBuilder.CreateSelectBodyExpression()
at Telerik.Windows.Data.Expressions.GroupDescriptorExpressionBuilder.CreateResultSelectorExpression()
at Telerik.Windows.Data.Expressions.GroupDescriptorExpressionBuilder.get_ResultSelectorExpression()
at Telerik.Windows.Data.Expressions.GroupDescriptorExpressionBuilderBase.CreateQuery()
at Telerik.Windows.Data.Expressions.GroupDescriptorCollectionExpressionBuilder.CreateChildQuery(GroupDescriptorExpressionBuilder childBuilder)
at Telerik.Windows.Data.Expressions.GroupDescriptorCollectionExpressionBuilder.CreateQuery()
at Telerik.Windows.Data.QueryableExtensions.GroupBy(IQueryable source, IEnumerable`1 groupDescriptors)
at Telerik.Windows.Data.QueryableExtensions.Aggregate(IQueryable source, IEnumerable`1 aggregateFunctions)
at Telerik.Windows.Controls.GridView.GridViewDataControl.CreateAggregateResults()
at Telerik.Windows.Controls.GridView.GridViewDataControl.CalculateAggregates()
at Telerik.Windows.Controls.GridView.GridViewDataControl.OnItemsCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
at System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(Object sender, NotifyCollectionChangedEventArgs e)
at Telerik.Windows.Data.DataItemCollection.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
at Telerik.Windows.Data.DataItemCollection.OnCollectionViewCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
at Telerik.Windows.Data.Listener`2.ReceiveWeakEvent(Object sender, TArgs args)
at Telerik.Windows.Data.WeakEvent.WeakListener`1.Handler(Object sender, TArgs args)
at Telerik.Windows.Data.QueryableCollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args)
at Telerik.Windows.Data.QueryableCollectionView.ProcessSynchronousCollectionChangedWithAdjustedArgs(NotifyCollectionChangedEventArgs originalArguments, Int32 adjustedOldIndex, Int32 adjustedNewIndex)
at Telerik.Windows.Data.QueryableCollectionView.ProcessSynchronousCollectionChanged(NotifyCollectionChangedEventArgs args)
at Telerik.Windows.Data.QueryableCollectionView.ProcessCollectionChanged(NotifyCollectionChangedEventArgs args)
at Telerik.Windows.Data.QueryableCollectionView.OnSourceCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)
at Telerik.Windows.Data.QueryableCollectionView.Telerik.Windows.Data.IWeakEventListener<System.Collections.Specialized.NotifyCollectionChangedEventArgs>.ReceiveWeakEvent(Object sender, NotifyCollectionChangedEventArgs args)
at Telerik.Windows.Data.WeakEvent.WeakListener`1.Handler(Object sender, TArgs args)
at System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(Object sender, NotifyCollectionChangedEventArgs e)
at System.Windows.Data.CollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args)
at System.Windows.Data.ListCollectionView.ProcessCollectionChangedWithAdjustedIndex(EffectiveNotifyCollectionChangedAction action, Object oldItem, Object newItem, Int32 adjustedOldIndex, Int32 adjustedNewIndex)
at System.Windows.Data.ListCollectionView.ProcessCollectionChangedWithAdjustedIndex(NotifyCollectionChangedEventArgs args, Int32 adjustedOldIndex, Int32 adjustedNewIndex)
at System.Windows.Data.ListCollectionView.ProcessCollectionChanged(NotifyCollectionChangedEventArgs args)
at System.Windows.Data.CollectionView.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)
at System.ServiceModel.DomainServices.Client.EntitySet`1.ListCollectionViewProxy`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
at System.ServiceModel.DomainServices.Client.EntitySet`1.ListCollectionViewProxy`1.OnSourceCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
at System.ServiceModel.DomainServices.Client.EntitySet`1.ListCollectionViewProxy`1.System.ServiceModel.DomainServices.Client.ICollectionChangedListener.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
at System.ServiceModel.DomainServices.Client.WeakCollectionChangedListener.SourceCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
at System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(Object sender, NotifyCollectionChangedEventArgs e)
at System.ServiceModel.DomainServices.Client.EntitySet.OnCollectionChanged(NotifyCollectionChangedAction action, Object affectedObject, Int32 index)
at System.ServiceModel.DomainServices.Client.EntitySet`1.OnCollectionChanged(NotifyCollectionChangedAction action, Object affectedObject, Int32 index)
at System.ServiceModel.DomainServices.Client.EntitySet.LoadEntity(Entity entity, LoadBehavior loadBehavior)
at System.ServiceModel.DomainServices.Client.EntitySet.LoadEntities(IEnumerable`1 entities, LoadBehavior loadBehavior)
at System.ServiceModel.DomainServices.Client.EntityContainer.LoadEntities(IEnumerable entities, LoadBehavior loadBehavior)
at System.ServiceModel.DomainServices.Client.DomainContext.CompleteLoad(IAsyncResult asyncResult)
--- End of inner exception stack trace ---
at System.ServiceModel.DomainServices.Client.OperationBase.Complete(Exception error)
at System.ServiceModel.DomainServices.Client.LoadOperation.Complete(Exception error)
at System.ServiceModel.DomainServices.Client.DomainContext.CompleteLoad(IAsyncResult asyncResult)
at System.ServiceModel.DomainServices.Client.DomainContext.<>c__DisplayClass1b.<Load>b__17(Object )