
Here’s a controller to add dynamic summaries to XAF Blazor ListViews until DevExpress includes them in the context menu for the footer.
public class SummaryController : ViewController<ListView>
{
SingleChoiceAction summaryAction;
public SummaryController()
{
summaryAction = new SingleChoiceAction(this, "summaryAction", PredefinedCategory.Edit);
summaryAction.Caption = "Summary";
summaryAction.ItemType = SingleChoiceActionItemType.ItemIsOperation;
summaryAction.Execute += SummaryAction_Execute;
}
protected override void OnActivated()
{
base.OnActivated();
summaryAction.Items.Clear();
var typ = ((TypeInfo)View.ObjectTypeInfo).Type;
var properties = typ.GetProperties();
foreach (var prop in properties)
{
if (prop.Name == "Oid" | prop.Name == "This" | prop.Name == "Loading" | prop.Name == "ClassInfo" | prop.Name == "Session" | prop.Name == "IsLoading" | prop.Name == "IsDeleted") continue;
var setPropiedadSummary = new ChoiceActionItem(typ.Name, prop.Name, null);
summaryAction.Items.Add(setPropiedadSummary);
AddSummary(setPropiedadSummary, typeof(GridSummaryItemType));
}
summaryAction.Items.Add(new ChoiceActionItem("Remove", "Remove", null));
}
void AddSummary(ChoiceActionItem parentItem, Type enumType)
{
EnumDescriptor ed = new EnumDescriptor(enumType);
foreach (object current in ed.Values)
{
if(current.ToString() == "Custom" || current.ToString() == "None") { continue; }
ChoiceActionItem item = new ChoiceActionItem(current.ToString(), current);
parentItem.Items.Add(item);
}
}
private void SummaryAction_Execute(object sender, SingleChoiceActionExecuteEventArgs e)
{
if (View.Editor is DxGridListEditor editor)
{
if (e.SelectedChoiceActionItem.Caption == "Remove")
{
editor.GridSummary.TotalSummary.Clear();
}
else
{
DxGridSummaryItemWrapper summary = new DxGridSummaryItemWrapper(new DxGridSummaryItemModel
{
SummaryType = (GridSummaryItemType)e.SelectedChoiceActionItem.Data,
FieldName = e.SelectedChoiceActionItem.ParentItem.Caption,
FooterColumnName = e.SelectedChoiceActionItem.ParentItem.Caption
});
if (!editor.GridSummary.TotalSummary.Any(s => s.SummaryType == ConvertSummaryItemType((GridSummaryItemType)e.SelectedChoiceActionItem.Data) & s.FieldName == e.SelectedChoiceActionItem.ParentItem.Caption))
{
editor.GridSummary.TotalSummary.Add(summary);
}
}
RefreshController refreshController = Frame.GetController<RefreshController>();
if (refreshController != null)
{
refreshController.RefreshAction.DoExecute();
}
}
}
private DevExpress.Data.SummaryItemType ConvertSummaryItemType(GridSummaryItemType summaryItemType)
{
return summaryItemType switch
{
GridSummaryItemType.Sum => DevExpress.Data.SummaryItemType.Sum,
GridSummaryItemType.Min => DevExpress.Data.SummaryItemType.Min,
GridSummaryItemType.Max => DevExpress.Data.SummaryItemType.Max,
GridSummaryItemType.Count => DevExpress.Data.SummaryItemType.Count,
GridSummaryItemType.Avg => DevExpress.Data.SummaryItemType.Average,
GridSummaryItemType.Custom => DevExpress.Data.SummaryItemType.Custom,
_ => DevExpress.Data.SummaryItemType.None
};
}
protected override void OnViewControlsCreated()
{
base.OnViewControlsCreated();
// Access and customize the target View control.
}
protected override void OnDeactivated()
{
// Unsubscribe from previously subscribed events and release other references and resources.
base.OnDeactivated();
}
}
Video: