Click here to Skip to main content
15,886,199 members
Articles / Web Development / ASP.NET

Group GridView Data

Rate me:
Please Sign up or sign in to vote.
4.85/5 (57 votes)
22 Aug 2014CPOL5 min read 233.5K   12K   135  
A custom GridView control which provides you an additional facility to group the data in gridview along with the facility to customise the Group Header and Group Footer
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.WebControls;
using System.Web.UI;
using System.Data;

// Written by Anurag Gandhi.
// Url: http://www.gandhisoft.com
// Contact me at: soft.gandhi@gmail.com

namespace GroupGridViewCtrl
{
    public class GroupContainer : WebControl, INamingContainer
    {
        private GridView _grid;
        private DataTable _SourceTable = new DataTable();
        private object _GroupColumnData;
        private string _GroupFilter = string.Empty;

        public object GroupColumnData
        {
            get { return _GroupColumnData; }
        }
        private string _GroupColumnName = string.Empty;

        public string GroupColumnName
        {
            get { return _GroupColumnName; }
        }

        /// <summary>
        /// Constructor for GroupContainer.//
        /// </summary>
        /// <param name="g">The instance of current GroupGridView Control</param>
        /// <param name="GroupColumnName">Name of the Column based on which data to be grouped</param>
        /// <param name="GroupColumnData">The data present in that GroupColumn of for this Group</param>
        public GroupContainer(GroupGridView g, string GroupColumnName, object GroupColumnData)
        {
            _grid = g;
            _SourceTable = (DataTable)g.DataSource;
            _GroupColumnName = GroupColumnName;
            _GroupColumnData = GroupColumnData;
            _GroupFilter = _GroupColumnName + "='" + _GroupColumnData.ToString() + "'";
        }

        public GridView GridView
        {
            get { return _grid; }
        }

        /// <summary>
        /// Gets the values of the DataColumn whose PropertyColumn equals to MatchingValues. If values are more than 1, it will return comma separated result.//
        /// </summary>
        /// <param name="DataColumn">The Column whose value is required</param>
        /// <param name="PropertyColumn">The column for filtering</param>
        /// <param name="MatchingValue">The data based on which PropertyColumn will be filtered</param>
        /// <returns>Values of DataColumn for MatchingValues from PropertyColumn</returns>
        public string GetValue(string DataColumn, string PropertyColumn, string MatchingValue)
        {
            string Filter = _GroupFilter + " and " +  PropertyColumn + " = '" + MatchingValue + "'";
            DataRow[] FilteredRows = _SourceTable.Select(Filter);
            string[] objList = FilteredRows.Select(x => (x.Field<object>(DataColumn) == null) ? string.Empty : (string)x.Field<object>(DataColumn)).ToArray();
            return objList.Aggregate((x, y) => x += ", " + y);
        }

        public object Average(string ColumnName)
        {
            return GetData(_GroupFilter, ColumnName, AggregateFunction.Average);
        }
        public object Count(string ColumnName)
        {
            return GetData(_GroupFilter, ColumnName, AggregateFunction.Count);
        }
        public object First(string ColumnName)
        {
            return GetData(_GroupFilter, ColumnName, AggregateFunction.First);
        }
        public object Last(string ColumnName)
        {
            return GetData(_GroupFilter, ColumnName, AggregateFunction.Last);
        }
        public object Max(string ColumnName)
        {
            return GetData(_GroupFilter, ColumnName, AggregateFunction.Max);
        }
        public object Min(string ColumnName)
        {
            return GetData(_GroupFilter, ColumnName, AggregateFunction.Min);
        }
        public object Sum(string ColumnName)
        {
            return GetData(_GroupFilter, ColumnName, AggregateFunction.Sum);
        }

        /// <summary>
        /// Retrives the data for matching RowField value and ColumnFields values with Aggregate function applied on them.
        /// </summary>
        /// <param name="Filter">DataTable Filter condition as a string</param>
        /// <param name="DataField">The column name which needs to spread out in Data Part of the Pivoted table</param>
        /// <param name="Aggregate">Enumeration to determine which function to apply to aggregate the data</param>
        /// <returns></returns>
        private object GetData(string Filter, string DataField, AggregateFunction Aggregate)
        {
            try
            {
                DataRow[] FilteredRows = _SourceTable.Select(Filter);
                object[] objList = FilteredRows.Select(x => x.Field<object>(DataField)).ToArray();

                switch (Aggregate)
                {
                    case AggregateFunction.Average:
                        return GetAverage(objList);
                    case AggregateFunction.Count:
                        return objList.Count();
                    case AggregateFunction.Exists:
                        return (objList.Count() == 0) ? "False" : "True";
                    case AggregateFunction.First:
                        return GetFirst(objList);
                    case AggregateFunction.Last:
                        return GetLast(objList);
                    case AggregateFunction.Max:
                        return GetMax(objList);
                    case AggregateFunction.Min:
                        return GetMin(objList);
                    case AggregateFunction.Sum:
                        return GetSum(objList);
                    default:
                        return null;
                }
            }
            catch (Exception ex)
            {
                return "#Error";
            }
        }

        private object GetAverage(object[] objList)
        {
            return objList.Count() == 0 ? null : (object)(Convert.ToDecimal(GetSum(objList)) / objList.Count());
        }
        private object GetSum(object[] objList)
        {
            return objList.Count() == 0 ? null : (object)(objList.Aggregate(new decimal(), (x, y) => x += Convert.ToDecimal(y)));
        }
        private object GetFirst(object[] objList)
        {
            return (objList.Count() == 0) ? null : objList.First();
        }
        private object GetLast(object[] objList)
        {
            return (objList.Count() == 0) ? null : objList.Last();
        }
        private object GetMax(object[] objList)
        {
            return (objList.Count() == 0) ? null : objList.Max();
        }
        private object GetMin(object[] objList)
        {
            return (objList.Count() == 0) ? null : objList.Min();
        }
    }
    public enum AggregateFunction
    {
        Count = 1,
        Sum = 2,
        First = 3,
        Last = 4,
        Average = 5,
        Max = 6,
        Min = 7,
        Exists = 8
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
India India
Anurag Gandhi is a Freelance Developer and Consultant, Architect, Blogger, Speaker, and Ex Microsoft Employee. He is passionate about programming.
He is extensively involved in Asp.Net Core, MVC/Web API, Node/Express, Microsoft Azure/Cloud, web application hosting/architecture, Angular, AngularJs, design, and development. His languages of choice are C#, Node/Express, JavaScript, Asp .NET MVC, Asp, C, C++. He is familiar with many other programming languages as well. He mostly works with MS SQL Server as the preferred database and has worked with Redis, MySQL, Oracle, MS Access, etc. also.
He is active in programming communities and loves to share the knowledge with others whenever he gets the time for it.
He is also a passionate chess player.
Linked in Profile: https://in.linkedin.com/in/anuraggandhi
He can be contacted at soft.gandhi@gmail.com

Comments and Discussions