У меня есть сетка 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*/)
?
Вы сказали: "сетка может использовать до примерно 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)))
)
И так далее, для каждой другой модели. С каждой моделью, имеющей свой собственный частичный вид, вы можете легко форматировать каждую сетку, чтобы она соответствовала ее модели, но все еще имела только один основной вид.