【问题标题】:Telerik grid custom column building/formattingTelerik 网格自定义列构建/格式
【发布时间】:2012-06-17 16:06:06
【问题描述】:

我有一个带有动态数据源的 Telerik 网格(该网格最多可以使用大约 10 个完全不同的模型来存储它的数据),所以我也必须动态地构建列(显然)。网格中的一列(对于某些型号)是一个以毫秒为单位的时间跨度的双精度。 我想做的是将这个双精度设置为时间跨度。telerik 代码如下所示:

<% Html.Telerik()
     .Grid(Model.DynamicGridDataSource)
     .Name("statisticalGrid")
     .Columns(a => GridHelper.GenerateColumns(a, Model.SelectedReport))
     .DataBinding(dataBinding => dataBinding.Ajax().Select("_SelectGrid", "Reports", new { reportId = Model.ReportId, dateFrom = Model.DateFrom, dateTo = Model.DateTo, date = Model.Date, AvailablePlans = Model.AvailablePlans }))
     .Sortable(GridSortSettingsBuilder => GridHelper.SortColumns(GridSortSettingsBuilder,
                                            Model.DynamicGridDataSource.GetType(),
                                            Model.SelectedReport))
     .Filterable()
     .Pageable(page => page.PageSize(25))
     .Reorderable(reorder => reorder.Columns(true))
     .Groupable
     (
         groupingSettingsBuilder => GridHelper.GroupColumns(groupingSettingsBuilder,
                                    Model.DynamicGridDataSource.GetType(),
                                    Model.SelectedReport)
     )
     .ClientEvents(events => events
          .OnColumnReorder("onReorder"))
     .Render();

GridHelper.GenerateColumns 看起来像这样:

public static void GenerateColumns(GridColumnFactory<dynamic> columnFactory, Company.Product.Data.Entity.Report reportStructure)
        {
            foreach (var columnLayout in reportStructure.ReportCols.OrderBy(o => o.ColumnSequence))
            {
                var columnBuilder = columnFactory.Bound(columnLayout.ColumnType);

                if (columnLayout.ColumnType.Equals("SessionLength") ||
                 columnLayout.ColumnType.Equals("AverageTime") ||
                 columnLayout.ColumnType.Equals("TotalTime") ||
                 columnLayout.ColumnType.Equals("CallTime"))
                {
                    // disable grouping
                    columnBuilder.Groupable(false);
                    string dataBindProperty = columnLayout.ColumnType;
                    if (columnLayout.DataFormat == "{0:T}")
                    {
                        //Even though the format looks like time ({0:T}), its actually a double which needs to be formatted here to look like a TimeSpan
                    }

                }

                if (!string.IsNullOrEmpty(columnLayout.Label))
                {
                    columnBuilder.Title(columnLayout.Label);
                }

                if (columnLayout.DataFormat != null && columnLayout.DataFormat == "{0:P}")
                {
                    columnBuilder.Format("{0:P}");
                }

                if (columnLayout.SumIndicator)
                {
                    if (columnLayout.DataFormat == "{0:T}")
                    {
                        AddAggregateToColumnTimeSpan(columnBuilder, Aggregate.Sum);
                    }
                    else
                    {
                        AddAggregateToColumn(columnBuilder, Aggregate.Sum);
                    }
                }

                if (columnLayout.HideIndicator)
                {
                    columnBuilder.Column.Hidden = true;
                }

            }
        }

我能够正确格式化页脚,但我不知道如何格式化列的其余部分,因为在 Telerik 代码的上下文之外,我无法访问 item 迭代器或任何东西.有什么建议/想法吗?也许columnFactory.Bound(columnType).Format(/*something*/)

【问题讨论】:

  • 我不知道你是否可以只使用格式。有没有办法使用像 Telerik 网格这样的模板?这样,您可以保留双精度,以便您可以求和,同时仍然可以通过在模板中转换将双精度显示为 TimeSpan。
  • @Daniel 好吧,我不确定! Theres GridColumnFactory.Template 但那将适用于整个网格,对吗?还有columnBuilder.Template(),看起来更接近我想要的。不过,不确定我将如何编写模板。也许这就是你可以提供帮助的地方。
  • 还有clientTemplate。不知道有什么区别
  • columnBuilder.Template() 听起来很有希望。我认为,如果您使用的是 ajax,ClientTemplate 将是。今晚我会试着多看这个。
  • @Daniel 谢谢!我只是不确定,因为实际上没有办法从 GridHelper 类内部访问数据,并且模板需要引用列中的项目,对吧?

标签: c# asp.net-mvc telerik telerik-grid


【解决方案1】:

您说过,“网格最多可以使用大约 10 种完全不同的模型来存储其数据”,所以也许不是试图在一个网格中表示所有这些模型,而是为每个模型设置一个网格。您可以使用某种机制将每个网格放在它自己的局部视图中,并使用一些机制来决定要加载哪个局部视图。这是一个简单的例子。

控制器

public ActionResult DynamicReport
{
    //Get your Model
    Model.model1 = model_01 = Model.DynamicGridDataSource.GetDynamicModel()
    //Get the name of what model is being returned so view knows which 
    //partial view to load
    ViewBag.Message = model_01.Name
    ...

    return View(model_01)
}

在视图中有一些条件逻辑来选择要加载的部分视图。

查看

<h2>View</h2>
@{
  string pView = "~/Views/Grid/Partial_01.cshtml";
  switch(ViewBag.Message)
  {
      case "p02":
      pView =  "~/Views/Grid/Parital_02.cshtml"
      break;
      .....
  }
}

@Html.Partial(pView)

PartialView_01

@model List<Models.Misc>
@(Html.Telerik().Grid(Model)
    .Name("Grid")
    .Columns(columns =>
    {
      columns.Bound(a => a.Id).Width(120);
      columns.Bound(a => a.Name).Width(100);
      columns.Bound(a => a.Value).Format("{0:#,##0.00}").Width(100).Title("Price");
    })
)

PartialView_02

@model List<Models.Temp>
@(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)))
) 

等等,对于每个不同的模型。每个模型都有自己的局部视图,您可以轻松地格式化每个网格以适合其模型,同时仍然只有一个主视图。

【讨论】:

  • 是的,这也是我的第一个想法,但我认为我们设置它的原因是因为它使得动态生成和实施新模型变得非常容易。我们将其用于网站的统计报告,因此经常会出现我们需要在网站上运行报告的新功能,并且使用当前设置它就像为它制作模型一样简单将其传递给视图。
  • 对,如果您的数据形状不断变化,这将是一场维护噩梦。
  • 但我想你给了我一个想法。我正在考虑将报告分组分为 3 或 4 个类别(可能一个用于与会话相关的内容,一个用于与活动相关的内容等),然后让每个 group(对应于一个局部视图)包含所有相关的列。然后,在每个组中,每个报告 将仅显示特定于该报告的列。这样,添加新报告只需向现有组添加一两列,或者每隔一段时间添加一个新组。这样就大大减少了维护。你怎么看?
  • 我想知道您的模型是否有一些自然分组。我认为这听起来是一个不错的计划。
  • 接受你的回答,因为它基本上是我需要的
猜你喜欢
  • 1970-01-01
  • 2012-07-10
  • 1970-01-01
  • 1970-01-01
  • 2011-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多