Example E3607
Visible to All Users

WinForms Data Grid - Display multiple group summaries within a group footer cell

This example creates a custom grid control (MyGridControl) that can display multiple group summary values within a group footer cell.

WinForms Data Grid - Display multiple group summaries within a group footer cell

Files to Review

See Also

Does this example address your development requirements/objectives?

(you will be redirected to DevExpress.com to submit your response)

Example Code

MultiGroupSummary/MyGridControl/MyGridControl.cs(vb)
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()); } } }
MultiGroupSummary/MyGridControl/MyGridFooterMenu.cs(vb)
C#
using DevExpress.XtraGrid.Menu; using System; using System.Collections.Generic; using System.Linq; using DevExpress.XtraGrid.Views.Grid; using DevExpress.XtraGrid.Views.Grid.ViewInfo; using DevExpress.XtraGrid; namespace Q354185.MyXtraGrid { public class MyGridFooterMenu : GridViewFooterMenu { public MyGridFooterMenu(GridView view) : base(view) { } public override void Init(object info) { var myInfo = info as GridHitInfo; base.Init(info); var rowSummaryItem = View.GetRowSummaryItem(myInfo.RowHandle, myInfo.Column); SetSummaryItem((GridGroupSummaryItem)rowSummaryItem.Key); if (myInfo.HitTest != GridHitTest.RowFooter) { return; } var item = myInfo.FooterCell.ColumnInfo.Tag as GridGroupSummaryItem; SetSummaryItem(item); } private void SetSummaryItem(GridGroupSummaryItem item) { if (item == null) { return; } SummaryItem = item; CreateItems(); } } }
MultiGroupSummary/MyGridControl/MyGridHandler.cs(vb)
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); } } }
MultiGroupSummary/MyGridControl/MyGridInfoRegistrator.cs(vb)
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); } } }
MultiGroupSummary/MyGridControl/MyGridView.cs
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); } } } }
MultiGroupSummary/MyGridControl/MyGridViewInfo.cs(vb)
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); } } }
MultiGroupSummary/ToolTipHelper.cs(vb)
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; } } }

Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.