Reputation: 295
I am using radzen library within a Blazer app. I have dynamic data and example of code below. My data is stored in IDictionary<string, object>. I am trying to add group footer template to the below code to create an aggregation row for each group on any columns that can be aggregated:
Using this demo: https://blazor.radzen.com/datagrid-group-footer-template
The code states to add:
<GroupFooterTemplate>
Group amount: <b>@String.Format(context.Data.Items.Cast<IDictionary<string, object>().Sum())</b>
</GroupFooterTemplate>
However I don’t know how to define the column in the sum()
Example code below to run the whole bit to see the issue. I am unable to aggregate the footer for each column when it’s dynamic code
@using System.Linq.Dynamic.Core
<RadzenDataGrid @bind-Value=@selectedItems Data="@data" TItem="IDictionary<string, object>"
AllowGrouping=“true”
ColumnWidth="200px"
AllowFiltering="true" FilterPopupRenderMode="PopupRenderMode.OnDemand" FilterMode="FilterMode.Advanced" AllowPaging="true" AllowSorting="true">
<Columns>
@foreach(var column in columns)
{
<RadzenDataGridColumn TItem="IDictionary<string, object>" Title="@column.Key" Type="column.Value"
Property="@GetColumnPropertyExpression(column.Key, column.Value)" >
<Template>
@context[@column.Key]
</Template>
</RadzenDataGridColumn>
}
</Columns>
</RadzenDataGrid>
@code {
IList<IDictionary<string, object>> selectedItems;
public IEnumerable<IDictionary<string, object>> data { get; set; }
public IDictionary<string, Type> columns { get; set; }
public string GetColumnPropertyExpression(string name, Type type)
{
var expression = $@"it[""{name}""].ToString()";
if (type == typeof(int))
{
return $"int.Parse({expression})";
}
else if (type == typeof(DateTime))
{
return $"DateTime.Parse({expression})";
}
return expression;
}
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
columns = new Dictionary<string, Type>()
{
{ "EmployeeID", typeof(int) },
{ "FirstName", typeof(string) },
{ "LastName", typeof(string) },
{ "HireDate", typeof(DateTime) },
};
foreach (var i in Enumerable.Range(0, 50))
{
columns.Add($"Column{i}", typeof(string));
}
data = Enumerable.Range(0, 100).Select(i =>
{
var row = new Dictionary<string, object>();
foreach (var column in columns)
{
row.Add(column.Key, column.Value == typeof(int) ? i :
column.Value == typeof(DateTime) ? DateTime.Now.AddMonths(i) : $"{column.Key}{i}");
}
return row;
});
}
}
I tried the following to use a dictionary indexer with column name as a string but can’t seem to get It to work
<GroupFooterTemplate>
Group amount: <b>@String.Format(context.Data.Items.Cast(IDictionary<string, object>)().Sum(x => x[x.Key]))</b>
</GroupFooterTemplate>
But this doesn’t work.
Upvotes: 0
Views: 1397
Reputation: 3
I also had issue with the Cast<>()
part and eventually extracted the sum logic to a separate method. (Note that for me the decimal datatype is the return type.)
decimal SumUp(IEnumerable items)
{
if (items is null) //nullcheck
{
throw new ArgumentNullException(nameof(items));
}
decimal total = 0;
foreach (var obj in items) //loop through group items
{
if (obj is YourObjectType item) //typecheck
{
total += item?.DecimalPropertyToBeSummedUp ?? 0;
}
}
return total;
}
Having that method in place, I thought it might be easier to find the issue and eventually called it from my GroupFooterTemplate
element like this:
<GroupFooterTemplate>
Group total: @SumUp(context.Data.Items)
</GroupFooterTemplate>
And like this, it works perfectly fine for me:
Upvotes: 0