Phi*_*idt 4 c# aggregate telerik telerik-grid asp.net-mvc-3
我有一个Telerik Grid,它有一个需要显示列总和的页脚.但是,其中一个列的数据类型是TimeSpanTelerik的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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是添加聚合的代码.这与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;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后我使用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();
}
Run Code Online (Sandbox Code Playgroud)
所以我想基本上问题是如何在telerik的Aggregate()方法中引用我的自定义聚合.如果你发现其他任何我做错了,请随意指出:)
编辑:刚刚注意到我必须CreateAggregateExpression(Expression, bool)在SumAggregate类中实现该方法.但是,并不完全确定如何实现它.
上次编辑:我使用自定义列构建器方法来构建columms,因此我不确定如何在此处进行格式化.我能够格式化总和,但不能格式化列的其余部分,因为在telerik调用的上下文之外,我无法访问item变量.这基本上是我的列构建逻辑:
在telerik代码中,
.Columns(a => GridHelper.GenerateColumns(a, Model.SelectedReport))
Run Code Online (Sandbox Code Playgroud)
生成列看起来像:
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)
}
Run Code Online (Sandbox Code Playgroud)
那么我将如何在此上下文中进行格式化?
您可以做的一件事是在"Days"中添加另一个代表TimeSpan的列.然后,您不必使用自定义聚合.
模型:
public List<Objects.Temp> GetTemp()
{
List<Objects.Temp> ltemp = new List<Objects.Temp>();
System.Random r = new Random();
Objects.Temp t = new Objects.Temp();
t.Name = "One";
t.start = DateTime.Now;
t.Value = r.NextDouble();
t.ts = DateTime.Today.AddDays(25) - t.start;
t.tsDays = t.ts.Days;
ltemp.Add(t);
t = new Objects.Temp();
t.Name = "Two";
t.start = DateTime.Now;
t.Value = r.NextDouble();
t.ts = DateTime.Today.AddDays(15) - t.start;
t.tsDays = t.ts.Days;
ltemp.Add(t);
t = new Objects.Temp();
t.Name = "Three";
t.start = DateTime.Now;
t.Value = r.NextDouble();
t.ts = DateTime.Today.AddDays(55) - t.start;
t.tsDays = t.ts.Days;
ltemp.Add(t);
return ltemp;
}
Run Code Online (Sandbox Code Playgroud)
视图:
@(Html.Telerik().Grid(Model)
.Name("Grid")
.Columns(columns =>
{
columns.Bound(o => o.Name)
.Aggregate(aggregates => aggregates.Count())
.FooterTemplate(@<text>Total Count: @item.Count</text>)
.GroupFooterTemplate(@<text>Count: @item.Count</text>);
columns.Bound(o => o.start)
.Width(200)
.Aggregate(aggreages => aggreages.Max())
//.Format("{0:c}")
.FooterTemplate(@<text>Max: @item.Max</text>)
.GroupFooterTemplate(@<text>Max: @item.Max</text>);
columns.Bound(o => o.Value)
.Width(200)
.Aggregate(aggregates => aggregates.Average())
.FooterTemplate(@<text>Average: @item.Average</text>)
.GroupFooterTemplate(@<text>Average: @item.Average</text>);
columns.Bound(o => o.ts)
.Width(100)
.Aggregate(aggregates => aggregates.Count().Min().Max())
.FooterTemplate(
@<text>
<div>Min: @item.Min</div>
<div>Max: @item.Max</div>
</text>)
.GroupHeaderTemplate(@<text>@item.Title: @item.Key (Count: @item.Count)</text>);
columns.Bound(o => o.tsDays)
.Width(100)
.Aggregate(aggregates => aggregates.Sum())
.FooterTemplate(
@<text>
<div>Sum: @item.Sum Days</div>
</text>)
.GroupHeaderTemplate(@<text>@item.Title: @item.Key (Sum: @item.Sum)</text>);
})
.Sortable()
Run Code Online (Sandbox Code Playgroud)
)
你得到的东西看起来像这样:

版本2
我更新了我的答案,以便只有一个TimeSpan列与TimeSpan相加并以TimeSpan格式显示它.列中的数据实际上是TimeSpan.TotalMilliseconds,但它使用模板显示为TimeSpan,并使用TimeSpan.FromMilliseconds方法格式化TimeSpan.我认为这样做比创建自定义聚合类更容易,如果甚至可以使用MVC扩展.
模型:
public class Temp
{
public string Name { get; set; }
public DateTime Start { get; set; }
public double Value { get; set; }
public TimeSpan ts { get; set; }
public double tsMilliseconds { get; set; }
}
List<Objects.Temp> ltemp = new List<Objects.Temp>();
System.Random r = new Random();
Objects.Temp t = new Objects.Temp();
t.Name = "One";
t.Start = DateTime.Now;
t.Value = r.NextDouble();
t.ts = DateTime.Today.AddDays(25) - t.Start;
t.tsMilliseconds = t.ts.TotalMilliseconds;
ltemp.Add(t);
t = new Objects.Temp();
t.Name = "Two";
t.Start = DateTime.Now;
t.Value = r.NextDouble();
t.ts = DateTime.Today.AddDays(15) - t.Start;
t.tsMilliseconds = t.ts.TotalMilliseconds;
ltemp.Add(t);
t = new Objects.Temp();
t.Name = "Three";
t.Start = DateTime.Now;
t.Value = r.NextDouble();
t.ts = DateTime.Today.AddDays(55) - t.Start;
t.tsMilliseconds = t.ts.TotalMilliseconds;
ltemp.Add(t);
Run Code Online (Sandbox Code Playgroud)
视图:
@(Html.Telerik().Grid(Model)
.Name("Grid")
.Columns(columns =>
{
columns.Bound(o => o.Name)
.Aggregate(aggregates => aggregates.Count())
.FooterTemplate(@<text>Total Count: @item.Count</text>)
.GroupFooterTemplate(@<text>Count: @item.Count</text>);
columns.Bound(o => o.Start)
.Template(@<text>@item.Start.ToShortDateString()</text>)
.Aggregate(aggreages => aggreages.Max())
.FooterTemplate(@<text>Max: @item.Max.Format("{0:d}")</text>)
.GroupHeaderTemplate(@<text>Max: @item.Max.Format("{0:d}")</text>)
.GroupFooterTemplate(@<text>Max: @item.Max.Format("{0:d}")</text>);
columns.Bound(o => o.Value)
.Width(200)
.Aggregate(aggregates => aggregates.Average())
.FooterTemplate(@<text>Average: @item.Average</text>)
.GroupFooterTemplate(@<text>Average: @item.Average</text>);
columns.Bound(o => o.tsMilliseconds)
.Width(100)
.Aggregate(aggregates => aggregates.Sum())
.Template(@<text>@TimeSpan.FromMilliseconds(@item.tsMilliseconds)</text>)
.Title("TimeSpan")
.FooterTemplate(
@<text>
<div>Sum: @TimeSpan.FromMilliseconds( @Convert.ToDouble( @item.Sum.Value.ToString() ) ) </div>
</text>)
//header if you group by TimeSpan
.GroupHeaderTemplate(@<text>@item.Title: @item.Key (Sum: @TimeSpan.FromMilliseconds(@Convert.ToDouble(@item.Sum.Value.ToString())))</text>)
//footer for grouping
.GroupFooterTemplate(@<text>Sum: @TimeSpan.FromMilliseconds(@Convert.ToDouble(@item.Sum.Value.ToString()))</text>);
})
.Sortable()
.Groupable(settings => settings.Groups(groups => groups.Add(o => o.Start)))
)
Run Code Online (Sandbox Code Playgroud)
没有分组产生这个:

分组产生了这个:

| 归档时间: |
|
| 查看次数: |
7918 次 |
| 最近记录: |