我有一个 Telerik Grid,它有一个需要显示列总和的页脚。但是,列的数据类型之一是TimeSpan
Telerik 的 Sum 聚合不支持。我需要使用GridBoundColumnBuilder.Aggregate()
来添加聚合。所以我想基本上问题是如何在 Telerik 的 Aggregate() 方法中引用我的自定义聚合。如果您发现我做错了什么,请随时指出 :) 使用这篇文章,我为我的自定义聚合创建了一个类,名为SumAggregate
,如下所示。(请注意,这还没有完成——它取自文章。它实际上实现了一个完全不同的聚合)
SumAggregate.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Telerik.Web.Mvc;
namespace TelerikPOC.CustomAggregates
{
public class SumAggregate : AggregateFunction
{
private System.Collections.Generic.List<object> distinctValues;
/// <summary>
/// Initializes the current aggregate function to its initial
/// state ready to accumulate and merge values.
/// </summary>
/// <remarks>
/// This method is called every time the accumulation of values
/// must start over for a new subset of records from the data source.
/// </remarks>
public void Init()
{
this.distinctValues = new System.Collections.Generic.List<object>();
}
/// <summary>
/// Accumulates new argument values to the current aggregate function.
/// </summary>
/// <remarks>
/// This aggregate function accepts one argument:
/// number - a numeric value to accumulate to the aggregate function;
/// </remarks>
public void Accumulate(object[] values)
{
if (!distinctValues.Contains(values[0]))
{
distinctValues.Add(values[0]);
}
}
/// <summary>
/// Merges the specified aggregate function to the current one.
/// </summary>
/// <param name="Aggregate">
/// Specifies an aggregate function to be merged to the current one.
/// </param>
/// <remarks>
/// This method allows the reporting engine to merge two accumulated
/// subsets of the same aggregate function into a single result.
/// </remarks>
public void Merge(AggregateFunction aggregate)
{
// Accumulate the values of the specified aggregate function.
System.Collections.Generic.List<object> sums1 = ((SumAggregate)aggregate).distinctValues;
foreach (object o in sums1)
{
this.Accumulate(new object[] { o });
}
}
/// <summary>
/// Returns the currently accumulated value of the aggregate function.
/// </summary>
/// <returns>
/// The currently accumulated numeric value of the aggregate function.
/// </returns>
public object GetValue()
{
return this.distinctValues.Count;
}
}
}
这是添加聚合的代码。这与index.cshtml中的以下代码冲突,但我想包含两种添加聚合的方法,只是为了给答案提供更多选项。这需要修改为使用自定义聚合而不是内置聚合,就像现在使用的那样。
GridHelper.cs(未完成——稍后将添加逻辑以循环遍历列等。顺便说一句,如果有人也想帮助我解决这个问题,我将非常感激,尽管我承认我没有还没试过。)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Telerik.Web.Mvc.UI.Fluent;
using TelerikPOC.CustomAggregates;
namespace TelerikPOC.Helpers
{
public class GridHelper
{
public static void AddAggregateToColumn(GridBoundColumnBuilder<dynamic> columnBuilder, string Aggregate)
{
switch (Aggregate)
{
case "Sum":
{
columnBuilder.Aggregate(aggregates => aggregates.Sum())
.GroupFooterTemplate(result => "Sum:" + result.Sum)
.ClientFooterTemplate("Sum: <#= Sum #>")
.FooterTemplate(result => "Total: " + result.Sum);
}
break;
}
}
}
}
然后我使用HtmlHelper
该类来构建/渲染 Telerik 网格,如下所示:
来自Index.cshtml:(一定要阅读右边的评论)
@{
Html.Telerik()
.Grid(Model)
.Name("statisticalGrid")
.Columns(columns =>
{
columns.Bound(o => o.PlanID).Aggregate(something); //This is probably going to be where
columns.Bound(o => o.SessionID).Aggregate(something); //I need the help. Just not sure
columns.Bound(o => o.TimeSpan).Aggregate(something); //how to reference the custom
columns.Bound(o => o.TimeSpanDouble).Aggregate(something); //aggregate here, in
}) //place of `something`
.Sortable(sortable => sortable.Enabled(true))
.Filterable()
.Pageable(page => page.PageSize(25))
.Reorderable(reorder => reorder.Columns(true))
.Groupable(groupable => groupable.Enabled(true))
.ClientEvents(events => events
.OnColumnReorder("onReorder"))
.Render();
}
所以我想基本上问题是如何在 Telerik 的Aggregate()
方法中引用我的自定义聚合。如果您发现我做错了什么,请随时指出:)
编辑:刚刚注意到我必须CreateAggregateExpression(Expression, bool)
在 SumAggregate 类中实现该方法。不过,不完全确定如何实现它。
最后编辑:我使用自定义列构建器方法来构建列,所以我不确定如何在这里进行格式化。我能够格式化总和,但不能格式化列的其余部分,因为在 Telerik 调用的上下文之外我无权访问该item
变量。这基本上是我的列构建逻辑的样子:
在 Telerik 代码中,
.Columns(a => GridHelper.GenerateColumns(a, Model.SelectedReport))
并生成列看起来像:
public static void GenerateColumns(GridColumnFactory<dynamic> columnFactory, Company.Project.Data.Entity.Report reportStructure)
{
foreach (var columnLayout in reportStructure.ReportCols.OrderBy(o => o.ColumnSequence))
{
GridBoundColumnBuilder<dynamic> columnBuilder = columnFactory.Bound(columnLayout.ColumnType);
//do other stuff here (add aggregates, formatting, etc)
}
那么在这种情况下我将如何进行格式化呢?