This example creates a custom grid control (MyGridControl
) that can display multiple group summary values within a group footer cell.
Files to Review
- MyGridControl.cs (VB: MyGridControl.vb)
- MyGridFooterMenu.cs (VB: MyGridFooterMenu.vb)
- MyGridHandler.cs (VB: MyGridHandler.vb)
- MyGridInfoRegistrator.cs (VB: MyGridInfoRegistrator.vb)
- MyGridView.cs (VB: MyGridViewInfo.vb)
- MyGridViewInfo.cs (VB: MyGridViewInfo.vb)
- ToolTipHelper.cs (VB: ToolTipHelper.vb)
See Also
Does this example address your development requirements/objectives?
(you will be redirected to DevExpress.com to submit your response)
Example Code
C#using System;
using System.Collections.Generic;
using System.Linq;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraGrid.Registrator;
namespace Q354185.MyXtraGrid {
public class MyGridControl : GridControl {
protected override BaseView CreateDefaultView() {
return CreateView("MyGridView");
}
protected override void RegisterAvailableViewsCore(InfoCollection collection) {
base.RegisterAvailableViewsCore(collection);
collection.Add(new MyGridInfoRegistrator());
}
}
}
C#using DevExpress.XtraGrid.Views.Grid.Handler;
using System;
using System.Collections.Generic;
using System.Linq;
using DevExpress.XtraGrid.Views.Grid;
namespace Q354185.MyXtraGrid {
public class MyGridHandler : GridHandler {
public MyGridHandler(GridView gridView)
: base(gridView) {
}
protected override DevExpress.XtraGrid.Menu.GridViewFooterMenu CreateGridViewFooterMenu(GridView gridView) {
return new MyGridFooterMenu(gridView);
}
}
}
C#using System;
using System.Collections.Generic;
using System.Linq;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraGrid.Registrator;
using DevExpress.XtraGrid.Views.Grid;
namespace Q354185.MyXtraGrid {
public class MyGridInfoRegistrator : GridInfoRegistrator {
public override BaseView CreateView(GridControl grid) {
return new MyGridView(grid as GridControl);
}
public override DevExpress.XtraGrid.Views.Base.ViewInfo.BaseViewInfo CreateViewInfo(BaseView view) {
return new MyGridViewInfo((GridView)view);
}
public override string ViewName {
get {
return "MyGridView";
}
}
public override DevExpress.XtraGrid.Views.Base.Handler.BaseViewHandler CreateHandler(BaseView view) {
return new MyGridHandler(view as MyGridView);
}
}
}
C#using System;
using System.Collections.Generic;
using System.Linq;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraGrid.Columns;
using DevExpress.Data;
namespace Q354185.MyXtraGrid {
public class MyGridView : GridView {
public MyGridView(GridControl ownerGrid)
: base(ownerGrid) {
}
public MyGridView() {
}
protected override string ViewName {
get {
return "MyGridView";
}
}
public int GetGroupFooterRowCount() {
if (IsDesignMode) {
return 0;
}
var footerRowCount = GetFooterRowCount();
if (footerRowCount.Count == 0) {
return 0;
}
return footerRowCount.Max(kvp => kvp.Value);
}
private Dictionary<GridColumn, int> GetFooterRowCount() {
var columnFooterRowCount = new Dictionary<GridColumn, int>();
foreach (GridGroupSummaryItem summary in GroupSummary) {
var col = summary.ShowInGroupColumnFooter;
if (col == null) {
continue;
}
if (columnFooterRowCount.ContainsKey(col)) {
columnFooterRowCount[col]++;
}
if (!(columnFooterRowCount.ContainsKey(col))) {
columnFooterRowCount.Add(col, 1);
}
}
return columnFooterRowCount;
}
protected override List<SummaryItem> SynchronizeSummary(System.Collections.IList gridSum, SummaryItemCollection summary)
{
var gridSumCollection = gridSum as GridGroupSummaryItemCollection;
if (gridSumCollection == null) {
return base.SynchronizeSummary(gridSum, summary);
}
var myGridSumCollection = new List<GridGroupSummaryItem>();
var groupFooterRowCount = GetGroupFooterRowCount();
MyGridSumCollectionAddSummary(gridSumCollection, myGridSumCollection);
var query = GetGroups(myGridSumCollection);
var tempSummaryItemList = new List<GridGroupSummaryItem>();
FillTempSummaryItemList(groupFooterRowCount, query, tempSummaryItemList);
GridSumCollectionAddSummaries(gridSumCollection, tempSummaryItemList);
return base.SynchronizeSummary(gridSum, summary);
}
private void MyGridSumCollectionAddSummary(GridGroupSummaryItemCollection gridSumCollection, List<GridGroupSummaryItem> myGridSumCollection) {
foreach (GridGroupSummaryItem summaryItem in gridSumCollection) {
myGridSumCollection.Add(summaryItem);
}
}
private IEnumerable<IGrouping<GridColumn, GridGroupSummaryItem>> GetGroups(List<GridGroupSummaryItem> gridSumCollection) {
var groups = from item in gridSumCollection
group item by item.ShowInGroupColumnFooter;
return groups;
}
private void FillTempSummaryItemList(int groupFooterRowCount, IEnumerable<IGrouping<GridColumn, GridGroupSummaryItem>> query, List<GridGroupSummaryItem> tempSummaryItemList) {
foreach (var group in query) {
GridGroupSummaryItem summaryItem = null;
GridColumn showInGroupColumnFooter = null;
var fieldName = string.Empty;
var summaryItemList = group.ToList();
for (var i = 0; i < groupFooterRowCount; i++) {
try {
summaryItem = summaryItemList[i];
} catch {
summaryItem = null;
}
if (summaryItem != null) {
fieldName = summaryItem.FieldName;
showInGroupColumnFooter = summaryItem.ShowInGroupColumnFooter;
continue;
}
if (fieldName != string.Empty && showInGroupColumnFooter != null) {
summaryItem = new GridGroupSummaryItem() { SummaryType = SummaryItemType.None, ShowInGroupColumnFooter = showInGroupColumnFooter, FieldName = fieldName };
tempSummaryItemList.Add(summaryItem);
}
}
}
AddEmptySummaryColumn(groupFooterRowCount, tempSummaryItemList);
}
private void GridSumCollectionAddSummaries(GridGroupSummaryItemCollection gridSumCollection, List<GridGroupSummaryItem> tempSummaryItemList) {
if (tempSummaryItemList.Count > 0) {
gridSumCollection.AddRange(tempSummaryItemList.ToArray());
}
}
private void AddEmptySummaryColumn(int groupFooterRowCount, List<GridGroupSummaryItem> tempSummaryItemList) {
var footerRowCount = GetFooterRowCount();
foreach (GridColumn col in Columns) {
if (footerRowCount.ContainsKey(col)) {
continue;
}
CreateEmptySummaries(col, tempSummaryItemList, groupFooterRowCount);
}
}
private void CreateEmptySummaries(GridColumn column, List<GridGroupSummaryItem> tempSummaryItemList, int groupFooterRowCount) {
GridGroupSummaryItem summaryItem = null;
GridColumn showInGroupColumnFooter = null;
var fieldName = string.Empty;
for (var i = 0; i < groupFooterRowCount - 1; i++) {
showInGroupColumnFooter = column;
fieldName = column.FieldName;
summaryItem = new GridGroupSummaryItem() { SummaryType = SummaryItemType.None, ShowInGroupColumnFooter = showInGroupColumnFooter, FieldName = fieldName };
tempSummaryItemList.Add(summaryItem);
}
}
}
}
C#using System;
using System.Collections.Generic;
using System.Linq;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraGrid.Views.Grid.ViewInfo;
using DevExpress.XtraGrid.Drawing;
using DevExpress.XtraGrid;
using System.Collections;
using DevExpress.XtraGrid.Columns;
using DevExpress.Data;
namespace Q354185.MyXtraGrid {
public class MyGridViewInfo : GridViewInfo {
public MyGridViewInfo(GridView gridView)
: base(gridView) {
}
protected override int CalcGroupFooterHeight() {
var myView = (MyGridView)View;
if (myView.GetGroupFooterRowCount() <= 0) {
return 0;
}
return base.CalcGroupFooterHeight() * myView.GetGroupFooterRowCount();
}
//protected override int GetMaxColumnFooterCount() {
// return ((MyGridView)View).GetGroupFooterRowCount();
//}
protected override void CalcRowCellsFooterInfo(GridRowFooterInfo fi, GridRowInfo ri) {
AddColumnsInfo(fi.RowHandle);
base.CalcRowCellsFooterInfo(fi, ri);
ChangeDisplayText(fi);
RemoveColumnsInfo();
}
private void AddColumnsInfo(int rowHandle) {
rowHandle = rowHandle >= 0 ? -1 : rowHandle;
var groupSummary = View.GetGroupSummaryValues(rowHandle);
var myGroupSummaryList = new List<DictionaryEntry>();
foreach (DictionaryEntry item in groupSummary) {
myGroupSummaryList.Add(item);
}
var query = from item in myGroupSummaryList
let summary = (GridGroupSummaryItem)item.Key
group item by summary.ShowInGroupColumnFooter;
foreach (var group in query) {
var myGroup = group.ToList();
for (var i = 1; i < myGroup.Count; i++) {
var sourceCInfo = ColumnsInfo[group.Key];
if (sourceCInfo == null) {
continue;
}
AddNewColumnsInfo(myGroup, i, sourceCInfo);
}
}
}
private void AddNewColumnsInfo(List<DictionaryEntry> group, int i, GridColumnInfoArgs initCellInfo) {
var cellInfo = new GridColumnInfoArgs(initCellInfo.Column);
cellInfo.Assign(initCellInfo);
cellInfo.Tag = group[i].Key as GridGroupSummaryItem;
cellInfo.Info.StartRow = i;
ColumnsInfo.Add(cellInfo);
}
private void RemoveColumnsInfo() {
var count = ColumnsInfo.OfType<GridColumnInfoArgs>().Where(ci => ci.Tag == null).Count() ;
while (ColumnsInfo.Count > count) {
ColumnsInfo.RemoveAt(count);
}
}
private void ChangeDisplayText(GridRowFooterInfo fi) {
foreach (GridFooterCellInfoArgs fci in fi.Cells) {
var rowSummaryItem = View.GetRowSummaryItem(fi.RowHandle, fci.Column);
if (rowSummaryItem.Key == null) {
continue;
}
var item = fci.ColumnInfo.Tag as GridGroupSummaryItem;
if (item == null) {
fci.Visible = ((GridGroupSummaryItem)rowSummaryItem.Key).SummaryType == SummaryItemType.None ? false : true;
continue;
}
fci.Visible = item.SummaryType == SummaryItemType.None ? false : true;
ChangeFooterCellDisplayText(fi, fci, item);
}
}
private void ChangeFooterCellDisplayText(GridRowFooterInfo fi, GridFooterCellInfoArgs fci, GridGroupSummaryItem item) {
var dEntry = GetCustomSummaryItemValue(fi.RowHandle, fci.Column, item);
fci.Visible = item.SummaryType == SummaryItemType.None ? false : true;
fci.Value = dEntry.Value;
fci.DisplayText = ((GridSummaryItem)dEntry.Key).GetDisplayText(dEntry.Value, false);
}
public virtual DictionaryEntry GetCustomSummaryItemValue(int rowHandle, GridColumn column, object summaryItem) {
if (column == null) {
return new DictionaryEntry();
}
var summary = View.GetGroupSummaryValues(rowHandle);
if (summary == null) {
return new DictionaryEntry();
}
foreach (DictionaryEntry dEntry in summary) {
var item = dEntry.Key as GridGroupSummaryItem;
if (item.ShowInGroupColumnFooter != column) {
continue;
}
if (item != summaryItem) {
continue;
}
return dEntry;
}
return new DictionaryEntry();
}
protected override void UpdateRowFooterInfo(GridRowInfo ri, GridRowFooterInfo fi) {
base.UpdateRowFooterInfo(ri, fi);
ChangeDisplayText(fi);
}
}
}
C#using DevExpress.Data;
using DevExpress.Utils;
using DevExpress.XtraGrid;
using Q354185.MyXtraGrid;
using System;
using System.Collections.Generic;
using System.Linq;
namespace MultiGroupSummary {
public class ToolTipHelper {
private MyGridControl gridCtrl;
public ToolTipHelper(MyGridControl myGridControl1) {
Init(myGridControl1);
}
private void Init(MyGridControl gridControl) {
gridCtrl = gridControl;
var toolTipController = new ToolTipController();
gridCtrl.ToolTipController = toolTipController;
toolTipController.GetActiveObjectInfo += new ToolTipControllerGetActiveObjectInfoEventHandler(ToolTipController_GetActiveObjectInfo);
}
private void ToolTipController_GetActiveObjectInfo(object sender, ToolTipControllerGetActiveObjectInfoEventArgs e) {
ToolTipControlInfo info = null;
var view = gridCtrl.GetViewAt(e.ControlMousePosition) as MyGridView;
if (view == null) {
return;
}
var hitInfo = view.CalcHitInfo(e.ControlMousePosition);
if (hitInfo == null) {
return;
}
var hitInfoFooterCell = hitInfo.FooterCell;
if (hitInfoFooterCell != null) {
var summaryItem = new GridGroupSummaryItem();
var tag = hitInfoFooterCell.ColumnInfo.Tag as GridGroupSummaryItem;
if (tag != null) {
summaryItem = tag;
} else {
var rowSummaryItem = view.GetRowSummaryItem(hitInfo.RowHandle, hitInfoFooterCell.Column);
summaryItem = rowSummaryItem.Key as GridGroupSummaryItem;
}
if (summaryItem == null) {
return;
}
if (summaryItem.SummaryType == SummaryItemType.None) {
return;
}
info = new ToolTipControlInfo(hitInfoFooterCell.Value, hitInfoFooterCell.DisplayText);
}
if (info == null) {
return;
}
e.Info = info;
}
}
}