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

SumFunction that sums based on another column value

12 Answers 541 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Michele
Top achievements
Rank 2
Michele asked on 16 Jan 2012, 05:58 PM
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

12 Answers, 1 is accepted

Sort by
0
Michele
Top achievements
Rank 2
answered on 17 Jan 2012, 08:37 AM
just an example on how to override default SumFunction class would be ok...
Thanks
0
Dimitrina
Telerik team
answered on 17 Jan 2012, 08:46 AM
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 >>
0
Michele
Top achievements
Rank 2
answered on 17 Jan 2012, 10:01 AM
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?

0
Dimitrina
Telerik team
answered on 17 Jan 2012, 10:25 AM
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 >>
0
Michele
Top achievements
Rank 2
answered on 17 Jan 2012, 12:40 PM
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
0
Michele
Top achievements
Rank 2
answered on 17 Jan 2012, 04:38 PM
It's possible that those aggregate won't worki fine with Ideablade's devforce?
0
Michele
Top achievements
Rank 2
answered on 18 Jan 2012, 12:38 PM
Any help on this?
0
Dimitrina
Telerik team
answered on 18 Jan 2012, 01:54 PM
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 >>

0
Michele
Top achievements
Rank 2
answered on 19 Jan 2012, 05:39 PM
Hello Didie,
where should I put this code? in my custom aggregator?
0
Dimitrina
Telerik team
answered on 19 Jan 2012, 05:46 PM
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 >>

0
guga
Top achievements
Rank 1
answered on 14 Sep 2012, 02:04 PM
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.
0
MiddleTommy
Top achievements
Rank 1
answered on 19 Feb 2013, 11:31 PM
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 )
Tags
GridView
Asked by
Michele
Top achievements
Rank 2
Answers by
Michele
Top achievements
Rank 2
Dimitrina
Telerik team
guga
Top achievements
Rank 1
MiddleTommy
Top achievements
Rank 1
Share this question
or