Hello,
I have a radGrid that populates with groups collapsed by default. The group header displays the group header title and aggregate count as expected. When a header is dragged to the GridGroupPanel, the new subgroup still has a header title, but the aggregate is lost for the new sub-group.
Here is a sample of my initial grouping:
Dim
expression
As
GridGroupByExpression =
New
GridGroupByExpression
Dim
gridGroupByField
As
GridGroupByField =
New
GridGroupByField
gridGroupByField =
New
GridGroupByField
gridGroupByField.FieldName =
"DGDesc"
gridGroupByField.HeaderText =
" "
gridGroupByField.HeaderValueSeparator =
" "
gridGroupByField.FormatString =
" <strong>{0}</strong> "
expression.SelectFields.Add(gridGroupByField)
expression.GroupByFields.Add(gridGroupByField)
gridGroupByField =
New
GridGroupByField
gridGroupByField.FieldName =
"ProspectusLnNo"
gridGroupByField.HeaderText =
" "
gridGroupByField.HeaderValueSeparator =
" "
gridGroupByField.FormatString =
" (Records: {0})"
gridGroupByField.Aggregate = GridAggregateFunction.Count
expression.SelectFields.Add(gridGroupByField)
radGridDocuments.MasterTableView.GroupByExpressions.Add(expression)
I had to add the GroupByFields first before adding the SelectField with the aggregate function or it would not work. Anyway:
When I try to modify the GroupsChanging event, the best I get is a blank subgroup:
If
e.Action = GridGroupsChangingAction.Group
Then
If
e.Expression.GroupByFields(0).FieldName <>
"ImgSRC"
Then
If
Not
IsGroupedByImgSRC(radGridDocuments.MasterTableView.GroupByExpressions)
Then
Dim
customerGroupField
As
GridGroupByField =
New
GridGroupByField()
customerGroupField.FieldName =
"ImgSRC"
customerGroupField.HeaderText =
" "
customerGroupField.HeaderValueSeparator =
" "
customerGroupField.FormatString =
" (Records: {0})"
customerGroupField.Aggregate = GridAggregateFunction.Count
e.Expression.SelectFields.Add(customerGroupField)
'e.Expression.GroupByFields.Insert(1, customerGroupField)
radGridDocuments.MasterTableView.GroupByExpressions.Add(e.Expression)
End
If
End
If
End
If
Thank you for any assistance.
11 Answers, 1 is accepted
One possible reason for the problematic behavior could be the way you create the grid in code behind. If you have the grid statically declared in mark-up, the rest of its declaration should be residing in the Page_Load event handler with a check if the Page is not PostBack.
Incorrect binding could also be a cause of the issue. Grouping requires either a declarative datasource or using advanced data-binding through the NeedDataSource event.
If none of this helps, please also post your grid declaration, so we can look for other possible causes of the problem.
Greetings,
Tsvetina
the Telerik team

<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="DocumentTrackingPI2.aspx.vb"
Inherits="XXXX.YYYY.DocumentTrackingPI2" %>
<%@ Register assembly="Telerik.Web.UI" namespace="Telerik.Web.UI" tagprefix="telerik" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<
html
xmlns
=
"http://www.w3.org/1999/xhtml"
>
<
head
runat
=
"server"
>
<
title
></
title
>
</
head
>
<
body
>
<
form
id
=
"form1"
runat
=
"server"
>
<
div
>
<
telerik:RadScriptManager
ID
=
"RadScriptManager1"
Runat
=
"server"
></
telerik:RadScriptManager
>
<
asp:UpdateProgress
ID
=
"UpdateProgress"
runat
=
"server"
AssociatedUpdatePanelID
=
"upMain"
>
<
ProgressTemplate
>
<
asp:Image
runat
=
"server"
ID
=
"imgProgress"
ImageUrl
=
"~/Images/Loading.gif"
/>
</
ProgressTemplate
>
</
asp:UpdateProgress
>
<
asp:UpdatePanel
ID
=
"upMain"
runat
=
"server"
>
<
ContentTemplate
>
<
table
id
=
"Table1"
runat
=
"server"
width
=
"99%"
>
<
tr
>
<
td
>
<
div
id
=
"fileTypeHeader"
>
<
asp:Label
ID
=
"lblFileTypeHeader"
runat
=
"server"
Text
=
""
></
asp:Label
>
</
div
>
</
td
>
</
tr
>
<
tr
>
<
td
>
<
div
id
=
"DocGridLayout"
style
=
"width: 930px"
>
<
table
>
<
tr
>
<
td
style
=
"width: 930px"
>
<
div
id
=
"RecordCount"
>
<
asp:Label
ID
=
"lblRecordCount"
runat
=
"server"
Text
=
"Label"
Font-Size
=
"Small"
></
asp:Label
>
</
div
>
</
td
>
</
tr
>
<
tr
>
<
td
align
=
"center"
>
<
div
style
=
"width: 930px"
>
<
asp:LinkButton
ID
=
"hlFilterHelpDoc"
runat
=
"server"
>Help for Sort and Filter Options</
asp:LinkButton
>
</
div
>
</
td
>
</
tr
>
<
tr
>
<
td
style
=
"width: 930px"
>
<
telerik:RadGrid
ID
=
"radGridDocuments"
Width
=
"100%"
AllowFilteringByColumn
=
"true"
AllowSorting
=
"true"
AllowPaging
=
"true"
PageSize
=
"2500"
runat
=
"server"
AutoGenerateColumns
=
"False"
ShowStatusBar
=
"true"
EnableLinqExpressions
=
"false"
GridLines
=
"None"
>
<
mastertableview
cellspacing
=
"-1"
DataKeyNames
=
"ImgID"
>
<
rowindicatorcolumn
>
<
HeaderStyle
Width
=
"20px"
/>
</
rowindicatorcolumn
>
<
expandcollapsecolumn
>
<
HeaderStyle
Width
=
"20px"
/>
</
expandcollapsecolumn
>
</
mastertableview
>
</
telerik:RadGrid
>
<
telerik:RadAjaxManager
ID
=
"RadAjaxManager1"
runat
=
"server"
></
telerik:RadAjaxManager
>
<
telerik:RadWindowManager
ID
=
"RadWindowManager1"
runat
=
"server"
Behavior
=
"Default"
Behaviors
=
"None"
Height
=
"800px"
KeepInScreenBounds
=
"True"
Width
=
"1000px"
>
<
Windows
>
<
telerik:RadWindow
runat
=
"server"
Behavior
=
"Close"
Behaviors
=
"Close"
InitialBehavior
=
"None"
Left
=
""
Modal
=
"True"
NavigateUrl
=
"~/Documents/FilterHelp.pdf#toolbar=0&navpanes=0"
OpenerElementID
=
"hlFilterHelpDoc"
style
=
"display: none;"
Title
=
"Filter Help"
Top
=
""
VisibleStatusbar
=
"False"
>
</
telerik:RadWindow
>
</
Windows
>
</
telerik:RadWindowManager
>
</
td
>
</
tr
>
</
table
>
</
div
>
</
td
>
</
tr
>
</
table
>
</
ContentTemplate
>
</
asp:UpdatePanel
>
</
div
>
<
div
>
</
div
>
<
asp:GridView
ID
=
"GridView1"
runat
=
"server"
>
</
asp:GridView
>
</
form
>
</
body
>
</
html
>
Hello,
I did create the grid statically as you mentioned, but almost all of the build is in code-behind, including using the 'NeedDataSource' event to populate the grid and manage the rebinds. Included is a copy of my aspx mark-up and the code-behind. We have also run into an issue that seems related. When we try to put a combobox in our filter template, the grouping stops working all together. We get script errors and the page crashes. I have removed this code from that which is included to keep focused, but I thought it was worth mentioning.
Imports System.Data
Imports System.Data.SqlClient
Imports System.Configuration
Imports XXXX.Administration
Imports System.Xml
Imports System.IO
Imports System.Diagnostics
Imports XXXX.YYYY.Security.Scrambling
Imports Telerik.Web.UI
Public Class DocumentTrackingPI2
Inherits XXXX.YYYY.Base.BasePage
Private dsSource As DataSet
Private dsDest As DataSet
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
'=========================================================================
'OLD CODE
' In this section we are pulling the components of the passed query string
' and assigning them to the base page structure object called "vs"
'=========================================================================
Dim test As String = ""
If Not IsPostBack Then
'Descramble query string parameter
Dim QueryString As NameValueCollection = DescrambleQueryString(Request.QueryString("DocumentTracking"))
Me.vs.CallingProcess = QueryString("CallingProcess")
'08/27/2008 SP: Need to set a cookie so that we can determine what the
'calling(Process) is even if the session time's out, that way we can
'prevent the user from being directed to the login page.
Dim aCookie As New HttpCookie("CallingProcess")
aCookie.Value = QueryString("CallingProcess")
Response.Cookies.Add(aCookie)
Me.vs.DatabaseName = QueryString("DatabaseName")
Me.vs.ServerName = QueryString("ServerName")
Me.vs.Filetype = QueryString("FileType")
Me.vs.PortfolioID = QueryString("PortfolioID")
Me.vs.CtrlID = QueryString("CtrlID") '05/19/2008 Robert Goen - Replaced LnID with CtrlID
Me.vs.PropertyID = QueryString("PropertyID")
Me.vs.PageTitle = QueryString("PageTitle") & " Documents"
Me.vs.SessionGuid = New Guid(QueryString("SessionGuid").ToString)
Me.vs.ColID = QueryString("ColID")
Me.vs.LnID = QueryString("LnID")
'Me.vs.LnSubID = QueryString("LnSubID")
Me.vs.DocumentViewingPageSearch = QueryString("DocumentViewingPageSearch")
'=========================================================================
' Set up a hyperlink to a help document that will assist people with
' how to filter and sort (as of this note 2/25/2011, have not received the
' help document from the technical writers).
'=========================================================================
hlFilterHelpDoc.Visible = True
'=========================================================================
BuildDocumentGrid()
GetDocumentGroupHeader()
End If
End Sub
Public Property Groups() As Hashtable
Get
If ViewState("Groups") Is Nothing Then
Dim res As New Hashtable()
ViewState("Groups") = res
Return res
End If
Return DirectCast(ViewState("Groups"), Hashtable)
End Get
Set(ByVal value As Hashtable)
ViewState("Groups") = value
End Set
End Property
Private Sub BuildDocumentGrid()
'=========================================================================
'NEW CODE
'=========================
'Telerik Grid Build
'=========================
' Initial settigs
With radGridDocuments
.Visible = True
.ShowStatusBar = True
.GroupingEnabled = True
.ShowGroupPanel = True
.AllowSorting = True
.SortingSettings.SortedBackColor = Drawing.Color.Aquamarine
.AllowFilteringByColumn = True
.AllowPaging = True
.PagerStyle.Position = GridPagerPosition.Top
.PagerStyle.Mode = GridPagerMode.NextPrev
.PagerStyle.AlwaysVisible = False
.AutoGenerateColumns = False
.Skin = "Web20"
.Width = Unit.Percentage(100)
.Height = Unit.Point(500)
.BorderStyle = BorderStyle.None
''======================================================================
''Disable case sensitive for filtering. NOTE: Setting case sensitivity
''can conflict with Linq for some reason according to Telerik.
radGridDocuments.GroupingSettings.CaseSensitive = False
radGridDocuments.EnableLinqExpressions = False
End With
With radGridDocuments.ClientSettings
.AllowDragToGroup = True
.Scrolling.AllowScroll = True
.Scrolling.UseStaticHeaders = True
End With
With radGridDocuments.MasterTableView
.GroupsDefaultExpanded = False
.AllowMultiColumnSorting = True
'.DataKeyNames = New String() {"ImgID"}
.PageSize = 2500
.Width = Unit.Percentage(100)
.HierarchyLoadMode = GridChildLoadMode.Client
.FilterItemStyle.HorizontalAlign = HorizontalAlign.Center
.HeaderStyle.HorizontalAlign = HorizontalAlign.Center
.HeaderStyle.Font.Bold = True
.HeaderStyle.Font.Size = FontUnit.Larger
.HorizontalAlign = HorizontalAlign.Left
.EnableViewState = True
End With
'Add Customers table
' Disable the filtering option for some of the grid columns by setting
' their "AllowFiltering" property to False.
Dim boundColumn As GridBoundColumn
boundColumn = New GridBoundColumn()
radGridDocuments.MasterTableView.Columns.Add(boundColumn)
boundColumn.DataField = "FullLnID"
boundColumn.HeaderText = "Asset ID"
boundColumn.AllowFiltering = False
boundColumn.ItemStyle.Width = Unit.Percentage(8)
boundColumn.HeaderStyle.Width = Unit.Percentage(8)
'This one will not be visible but we count records on
boundColumn = New GridBoundColumn()
radGridDocuments.MasterTableView.Columns.Add(boundColumn)
boundColumn.DataField = "ProspectusLnNo"
boundColumn.HeaderText = "Prospectus ID"
boundColumn.Visible = False
boundColumn = New GridBoundColumn()
radGridDocuments.MasterTableView.Columns.Add(boundColumn)
boundColumn.DataField = "PropertyName"
boundColumn.HeaderText = "Collateral Name"
boundColumn.AutoPostBackOnFilter = True
boundColumn.ItemStyle.Width = Unit.Percentage(16)
boundColumn.HeaderStyle.Width = Unit.Percentage(16)
'This one will not be visible but is grouped on
boundColumn = New GridBoundColumn()
radGridDocuments.MasterTableView.Columns.Add(boundColumn)
boundColumn.DataField = "DGDesc"
boundColumn.HeaderText = "Document Group"
boundColumn.Visible = False
'=============================================================================
'Format the link column:
' To populate the Telerik DataNavigateUrlFormatString I could not use the standard
' means provided by Telerik. This is why you do not see it here. We encrypt the
' query string, and since it is different from record to record, I had to populate
' the link in the ItemDataBound event. The example listed on the Telerik posting
' shows two ways to do this. To read the Telerik posting go to:
'=============================================================================
Dim linkColumn As GridHyperLinkColumn
linkColumn = New GridHyperLinkColumn
radGridDocuments.MasterTableView.Columns.Add(linkColumn)
linkColumn.DataTextFormatString = "{0}"
''--------------------------
''End format the link column
''--------------------------
linkColumn.UniqueName = "DTDesc"
linkColumn.DataTextField = "DTDesc"
linkColumn.HeaderText = "Document Type"
linkColumn.AutoPostBackOnFilter = True
linkColumn.ItemStyle.Width = Unit.Percentage(26)
linkColumn.HeaderStyle.Width = Unit.Percentage(26)
boundColumn = New GridBoundColumn()
radGridDocuments.MasterTableView.Columns.Add(boundColumn)
boundColumn.DataField = "DocTitle"
boundColumn.HeaderText = "Document Title"
boundColumn.AutoPostBackOnFilter = True
boundColumn.ItemStyle.Width = Unit.Percentage(26)
boundColumn.HeaderStyle.Width = Unit.Percentage(26)
boundColumn = New GridBoundColumn()
radGridDocuments.MasterTableView.Columns.Add(boundColumn)
boundColumn.DataField = "EffDt"
boundColumn.HeaderText = "Effective Date"
boundColumn.AutoPostBackOnFilter = True
boundColumn.ItemStyle.Width = Unit.Percentage(12)
boundColumn.HeaderStyle.Width = Unit.Percentage(12)
'This one will not be visible but we rely on its unique value
boundColumn = New GridBoundColumn()
radGridDocuments.MasterTableView.Columns.Add(boundColumn)
boundColumn.DataField = "ImgID"
boundColumn.HeaderText = "Image ID"
boundColumn.Visible = False
boundColumn = New GridBoundColumn()
radGridDocuments.MasterTableView.Columns.Add(boundColumn)
boundColumn.DataField = "ImgPGCT"
boundColumn.HeaderText = "Pages"
boundColumn.AutoPostBackOnFilter = True
boundColumn.ItemStyle.Width = Unit.Percentage(12)
boundColumn.HeaderStyle.Width = Unit.Percentage(12)
boundColumn = New GridBoundColumn()
radGridDocuments.MasterTableView.Columns.Add(boundColumn)
boundColumn.DataField = "ImgSRC"
boundColumn.HeaderText = "Source"
boundColumn.Visible = False
'==========================================================================
' Now we group and set up our counts for the groupings.
' The fields used are non-visible to the user. They do not neeed to be seen
' and, since they are not, help with managing events. This is because we
' do not have to code for user interaction with the columns.
'===========================================================================
Dim expression As GridGroupByExpression = New GridGroupByExpression
Dim gridGroupByField As GridGroupByField = New GridGroupByField
gridGroupByField = New GridGroupByField
gridGroupByField.FieldName = "DGDesc"
gridGroupByField.HeaderText = " "
gridGroupByField.HeaderValueSeparator = " "
gridGroupByField.FormatString = " <
strong
><
larger
>{0}</
larger
></
strong
> "
expression.SelectFields.Add(gridGroupByField)
expression.GroupByFields.Add(gridGroupByField)
gridGroupByField = New GridGroupByField
gridGroupByField.FieldName = "ProspectusLnNo"
gridGroupByField.HeaderText = " "
gridGroupByField.HeaderValueSeparator = " "
gridGroupByField.FormatString = " (Records: {0})"
gridGroupByField.Aggregate = GridAggregateFunction.Count
expression.SelectFields.Add(gridGroupByField)
radGridDocuments.MasterTableView.GroupByExpressions.Add(expression)
End Sub
Private Function GetDocumentGroupHeader() As String
Dim returnString As String = Me.vs.PageTitle
Me.lblFileTypeHeader.Text = returnString
Return returnString
End Function
Private Sub radGridDocuments_DataBound(ByVal sender As Object, ByVal e As System.EventArgs) Handles radGridDocuments.DataBound
For Each item As GridGroupHeaderItem In radGridDocuments.MasterTableView.GetItems(GridItemType.GroupHeader)
If Groups.ContainsKey(item.DataCell.Text) Then
item.Expanded = CBool(Groups(item.DataCell.Text))
End If
Next
End Sub
Private Sub radGridDocuments_GroupsChanging(ByVal source As Object, ByVal e As Telerik.Web.UI.GridGroupsChangingEventArgs) Handles radGridDocuments.GroupsChanging
Groups.Clear()
For Each item As GridGroupHeaderItem In radGridDocuments.MasterTableView.GetItems(GridItemType.GroupHeader)
Groups(item.DataCell.Text) = item.Expanded
Next
End Sub
Private Sub radGridDocuments_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles radGridDocuments.Init
'=================================================================
'Customize the Filters
' Determine which filters are available
'=================================================================
Dim menu As GridFilterMenu = radGridDocuments.FilterMenu
Dim i As Integer = 0
While i < menu.Items.Count
If menu.Items(i).Text = "NoFilter" Or _
menu.Items(i).Text = "Contains" Or _
menu.Items(i).Text = "EqualTo" Or _
menu.Items(i).Text = "GreaterThan" Or _
menu.Items(i).Text = "LessThan" Then
i = i + 1
Else
menu.Items.RemoveAt(i)
End If
End While
End Sub
Private Sub radGridDocuments_ItemCommand(ByVal source As Object, ByVal e As Telerik.Web.UI.GridCommandEventArgs) Handles radGridDocuments.ItemCommand
' This is used as part of state maintenance for expanded columns
If e.CommandName = RadGrid.ExpandCollapseCommandName Then
Groups(DirectCast(e.Item, GridGroupHeaderItem).DataCell.Text) = Not e.Item.Expanded
End If
End Sub
Private Sub radGridDocuments_ItemDataBound(ByVal sender As Object, ByVal e As Telerik.Web.UI.GridItemEventArgs) Handles radGridDocuments.ItemDataBound
' Here we are just getting the total records count. There are lots of ways
' to do this, but I just picked this one. You could also assign a count from
' the data pull.
If TypeOf e.Item Is GridPagerItem Then
lblRecordCount.Text = "Total Records: " & CType(e.Item, GridPagerItem).Paging.DataSourceCount.ToString()
End If
' To populate the Telerik DataNavigateUrlFormatString I could not use the standard
' means provided by Telerik. We encrypt the query string, and since it is different
' from record to record, I had to populate the link in this event. The example listed
' on the Telerik posting below, shows a way to do this by accessing the Telerik
' parameters, but the second method, which is to just change the NavigateUrl is cleaner
' for our purposes.
' To read the Telerik posting that helped me go to:
If (TypeOf e.Item Is GridDataItem) Then
Dim dataItem As GridDataItem = DirectCast(e.Item, GridDataItem)
Dim link As HyperLink = DirectCast(dataItem("DTDesc").Controls(0), HyperLink)
Dim qs As String = String.Format("DocTrackID={0}&Source={1}&SystemID={2}&PortfolioID={3}", dataItem("ImgID").Text, dataItem("ImgSRC").Text, Me.vs.CallingProcess, Me.vs.PortfolioID.ToString)
Dim scrambled_qs As String = Scramble(qs)
link.NavigateUrl = String.Format("~/ContentPages/DocumentViewing.aspx?DocumentRequested={0}", scrambled_qs)
End If
End Sub
Private Sub radGridDocuments_NeedDataSource(ByVal source As Object, ByVal e As Telerik.Web.UI.GridNeedDataSourceEventArgs) Handles radGridDocuments.NeedDataSource
' Here we are pulling the data needed for binding to the grid
' Since many of the features require a rebinding, but do not
' play well with a straight call to the rebind() method, we use
' this event which handles any time a rebind is needed.
Dim docMgmt As New DocMgmtService.DocTrackingService
Dim ds As DataSet
'dsSource = New DataSet
'dsDest = New DataSet
'03/09/2011 - VAB: Not sure we need this for strictly PI2, but it does not hurt to leave it in.
'03/30/2010 SP: The PropertyID was changed and is a unique ID independent of
' ctrlID so we can find the record just off of the PropertyID
If Not Me.vs.PropertyID = String.Empty AndAlso Not Me.vs.PropertyID = "0" Then
Me.vs.CtrlID = "0"
End If
ds = docMgmt.SelectRecords_CI2(Me.vs.PortfolioID, Me.vs.Filetype, Me.vs.CtrlID, Me.vs.PropertyID, Me.vs.CallingProcess, Me.vs.DatabaseName, Me.vs.ServerName, Me.vs.SessionGuid)
Dim myDataView As DataView = ds.Tables("Documents").DefaultView
radGridDocuments.DataSource = myDataView
End Sub
'Taken from Microsoft MSDN site (NOTE: Also found on Telerik site) Used to get
'distinct rows from a table (will use in filter dropdown list)
Public Function SelectDistinct(ByVal TableName As String, _
ByVal SourceTable As DataTable, _
ByVal FieldName As String) As DataTable
Dim dt As New DataTable(TableName)
dt.Columns.Add(FieldName, SourceTable.Columns(FieldName).DataType)
Dim dr As DataRow, LastValue As New Object
For Each dr In SourceTable.Select("", FieldName)
If LastValue Is Nothing OrElse Not ColumnEqual(LastValue, dr(FieldName)) Then
LastValue = dr(FieldName)
dt.Rows.Add(New Object() {LastValue})
End If
Next
If Not dsSource Is Nothing Then dsDest.Tables.Add(dt)
Return dt
End Function
Private Function ColumnEqual(ByVal A As Object, ByVal B As Object) As Boolean
'
' Compares two values to determine if they are equal. Also compares DBNULL.Value.
'
' NOTE: If your DataTable contains object fields, you must extend this
' function to handle the fields in a meaningful way if you intend to group on them.
'
If A Is DBNull.Value And B Is DBNull.Value Then Return True ' Both are DBNull.Value.
If A Is DBNull.Value Or B Is DBNull.Value Then Return False ' Only one is DBNull.Value.
Return A = B ' Value type standard comparison
End Function
Private Sub radGridDocuments_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles radGridDocuments.PreRender
Dim test As String = ""
End Sub
End Class
Actually, looking at your code I see that I may have misunderstood you. Where are you expecting the group aggregates to show? I do not see anywhere in your code enabling the group footer and this is where the aggregates are shown by default. Could you please confirm if you are talking about the group footer and have you set ShowGroupFooter="true" for the MasterTableView?.
Or if I am getting your idea wrong, please elaborate a little more on what do you mean by saying that the aggregate is lost for the new sub-group.
All the best,
Tsvetina
the Telerik team

I aggregate in the header. I have enclosed two .JPG screenshots (before and after) showing what I mean. I did not use footers. I may if needed.
When grouping using the GroupPanel, by default aggregates are not shown in the GroupHeaderItem. You can try using code logic similar to that in the following example and see if it works in your case:
Performing calculations in group header
Regards,
Tsvetina
the Telerik team

I tried using your example with a slight modification:
If
TypeOf
e.Item
Is
GridGroupHeaderItem
Then
Dim
item
As
GridGroupHeaderItem =
CType
(e.Item, GridGroupHeaderItem)
Dim
groupDataRow
As
DataRowView =
CType
(e.Item.DataItem, DataRowView)
item.DataCell.Text = (item.DataCell.Text +
" Records: "
)
item.DataCell.Text = (item.DataCell.Text + _
groupDataRow(
"count"
).ToString)
End
If
When it loads, the count is there (as before), but if I drag a column into the GridGroupPanel I get an error ("Count is neither a DataColumn nor a DataReation for table"). It works fine on page load, it just does not seem to like when I create a new group by dragging the column.
Then, a possible approach would be to set ShowGroupFooter="true" in the MasterTableView and wire the PreRender event of RadGrid. There, you can loop through the group footers, take the count from there and add it to the respective GridGroupHeaderItems. In case you do not want the footers to be visible to the users, you can hide them after taking their values.
The thing here is that RadGrid does not automatically calculate the group aggregates if you do not have the footers enabled, that is why you can use them to trigger this calculation.
In order to access all group headers and all group footers you can use the GetItems(itemType) method of the MasterTableView:
RadGrid2.MasterTableView.GetItems(GridItemType.GroupFooter)
'returns an array of all group footer items
RadGrid2.MasterTableView.GetItems(GridItemType.GroupHeader)
'returns an array of all group header items
Kind regards,
Tsvetina
the Telerik team

So I now get aggregates in my sub groups, but the counts are off. How do I tie the content from the footer the the appropriate header? Here is my adjusted code based on the advice you gave me in the last post:
'Aggregate sub groups
Dim
headerItems
As
GridItem() = radGridDocuments.MasterTableView.GetItems(GridItemType.GroupHeader)
Dim
footerItems
As
GridItem() = radGridDocuments.MasterTableView.GetItems(GridItemType.GroupFooter)
Dim
index
As
Integer
= 0
For
Each
groupFooterItem
As
GridItem
In
footerItems
Dim
groupFooterCount
As
String
Dim
groupHeaderItem
As
GridItem = TryCast(headerItems(index), GridItem)
Dim
myFooterItem
As
GridGroupFooterItem = TryCast(groupFooterItem, GridGroupFooterItem)
Dim
myHeaderItem
As
GridGroupHeaderItem = TryCast(groupHeaderItem, GridGroupHeaderItem)
groupFooterCount = myFooterItem(
"FullLnID"
).Text
myHeaderItem.DataCell.Text = myHeaderItem.DataCell.Text &
" (Sub Group Record Count: "
&
CType
(groupFooterCount,
String
) &
")"
index += 1
Next

I came up with a solution, using the help Tsvetina at Telerik gave on how to pull the header/footer items. The aggregates seem to be working now, but will have to fully test when we move to our test servers and try on various browsers. Anyway, I enabled the footer, added an aggregate to one of the columns to be used in the footer (as suggested by Telerik) and then in the code behind I pulled the information and added it to the header. There was an offset in the counts due, I think, to the way I do the page load with a group already set. I also did not want the footer information added to the main group (GroupLevel 0). I could not find how to access GroupLevel, but noticed that GroupIndex was 0 for the first grouping and x_y for any subsequent groupings (when a column was dragged to the grouping bar), so I used the "_" to identify this and act accordingly.
In the .aspx page I added the Aggregate="Count":
<
telerik:GridBoundColumn
DataField
=
"FullLnID"
HeaderText
=
"Asset ID"
SortExpression
=
"FullLnID"
UniqueName
=
"FullLnID"
Visible
=
"true"
DataType
=
"system.String"
ConvertEmptyStringToNull
=
"true"
AllowFiltering
=
"true"
HeaderStyle-Width
=
"75px"
Aggregate
=
"Count"
>
<
FilterTemplate
>
<
telerik:RadComboBox
ID
=
"cbFullLnID"
DataTextField
=
"FullLnID"
DataValueField
=
"FullLnID"
AppendDataBoundItems
=
"true"
Text='<%# TryCast(Container, GridItem).OwnerTableView.GetColumn("FullLnID").CurrentFilterValue %>'
runat="server" Width="55px"
DropDownWidth="75px"
NoWrap="true"
AllowCustomText="true"
OnClientTextChange="cbIndexChanged"
OnClientSelectedIndexChanged="cbIndexChanged"
MarkFirstMatch="true">
<
Items
>
</
Items
>
</
telerik:RadComboBox
>
</
FilterTemplate
>
</
telerik:GridBoundColumn
>
Also, do not forget to add "ShowGroupFooter="true" to the MasterTableView:
<
MasterTableView
AutoGenerateColumns
=
"False"
AllowFilteringByColumn
=
"True"
AllowSorting
=
"True"
GroupLoadMode
=
"Client"
GroupsDefaultExpanded
=
"false"
Width
=
"100%"
Name
=
"Master"
DataKeyNames
=
"DGDesc"
CommandItemDisplay
=
"Top"
AllowNaturalSort
=
"false"
AllowMultiColumnSorting
=
"true"
ShowGroupFooter
=
"true"
>
In the code behind radGrid_PreRender I added:
'=========================================================================
' VAB - 29 March 2011
'=========================================================================
' Used to manage aggregates for sub-groups created when a column header
' is dragged to the grouping bar.
'
'The first two dimensions are arrays of the header and footer items.
Dim
headerItems
As
GridItem() = radGridDocuments.MasterTableView.GetItems(GridItemType.GroupHeader)
Dim
footerItems
As
GridItem() = radGridDocuments.MasterTableView.GetItems(GridItemType.GroupFooter)
Dim
headerSize
As
Integer
= headerItems.Length
'We cycle through the the header and footer items to pull the count (aggregate
'was set on the .aspx page) from the footer and put into the header. We offset
'with -2 at the end because we do not need the count from the grand total row
'that is created. Also, I was finding that the footer and header indexes were
'"off" due to the way we start the page (with a group already set up), so we
'do a +1 to account for that so that the sub-group records counts match.
For
index
As
Integer
= 0
To
headerSize - 2
Dim
groupFooterCount
As
String
Dim
groupFooterItem
As
GridItem = TryCast(footerItems(index), GridItem)
Dim
groupHeaderItem
As
GridItem = TryCast(headerItems(index + 1), GridItem)
Dim
myFooterItem
As
GridGroupFooterItem = TryCast(groupFooterItem, GridGroupFooterItem)
Dim
myHeaderItem
As
GridGroupHeaderItem = TryCast(groupHeaderItem, GridGroupHeaderItem)
'The first group is set up on page load and the formatting for its aggregates
'are different, so we look to see if we are looking at a sub-group (sub-groups
'have "_" seperating their group index).
If
myHeaderItem.GroupIndex.Contains(
"_"
)
Then
groupFooterCount = myFooterItem(
"FullLnID"
).Text
myHeaderItem.DataCell.Text = myHeaderItem.DataCell.Text &
" (Sub Group Record Count: "
&
CType
(groupFooterCount,
String
) &
")"
End
If
'We do not want to see the footer, since all we care about is a record count
'and we put it in the header. That said, it was necessary to include the
'footer to get the aggregate for the sub-groups so we needed it up to this
'point.
myFooterItem.Visible =
False
Next
I hope this helps anyone trying to do the same thing. Also, if any of you come up with a "cleaner" way of doing this, please post it. Currently, I am trying to figure out how to manage to index offsets when people drag more than one or two columns into the group bar.

This will be my last post, I think, but I figured out the problem with matching the footer aggregate information to the appropriate header. Basically the problem was to match the appropriate Header GroupIndex with the appropriate Footer GroupIndex. I basically built an ArrayList of structures to work this. If anyone comes up with a better way, please share. Anyway, the structure looks like this:
'=========================================================================
' VAB - 29 March 2011
'=========================================================================
' Used to manage aggregates for sub-groups created when a column header.
' See notes (with same date stamp as this note) in radGridDocuments_PreRender.
Public
Structure
GroupInfo
Public
Property
strucHeaderIndex
Public
Property
strucHeaderGroupIndex
Public
Property
strucFooterIndex
End
Structure
and the code in the RadGrid_PreRender now looks like this:
'=========================================================================
' VAB - 29 March 2011
'=========================================================================
' Used to manage aggregates for sub-groups created when a column header
' is dragged to the grid grouping panel. We want the aggregate information
' in the header and do not want to see the footer.
'
'The first two dimensions are arrays of the header and footer items.
Dim
headerItems
As
GridItem() = radGridDocuments.MasterTableView.GetItems(GridItemType.GroupHeader)
Dim
footerItems
As
GridItem() = radGridDocuments.MasterTableView.GetItems(GridItemType.GroupFooter)
'I had a real problem with managing the footer aggregates and paring
'it with the appropriate header because the footer would do a "parent
'group" total under the last child group in it. The GroupIndexes
'were a way to match up the appropriate footer information with
'its matching header row. To make this happen, I built a structure
'(GroupInfo) to hold the Header index, Footer index, and HeaderGroup
'index. I then created an arraylist of these structures and initially
'populated the structures with the header information. I used header
'since it starts with a HeaderGroupIndex of 0 and the FooterGroupIndex
'starts with 0_0. Anyway, after I had the ArrayList of structures
'populated, I go through the footer array and match the FooterGroupIndex
'to the appropriate structure with the same HeaderGroupIndex and
'assign the Footer index to that structure. What we end up with is the
'index for the right footer information going to the right header
'information. For example, Index 3 of each of the original header and
'footer arrays above might have matched HeaderIndex 2_0 and FooterIndex 2_2.
'Now we have Index 3 of the arraylist matching HeaderIndex 2_0 to
'FooterIndex 2_0.
Dim
headerSize
As
Integer
= headerItems.Length
Dim
footerGroupIndex
As
String
=
""
Dim
aryGroupInfo
As
New
ArrayList
Dim
myGroupInfo
As
GroupInfo
For
index
As
Integer
= 0
To
headerSize - 1
myGroupInfo =
New
GroupInfo
myGroupInfo.strucHeaderIndex = index
myGroupInfo.strucHeaderGroupIndex = headerItems(index).GroupIndex
aryGroupInfo.Add(myGroupInfo)
Next
Dim
my2GroupInfo
As
GroupInfo
For
index
As
Integer
= 0
To
headerSize - 1
footerGroupIndex = footerItems(index).GroupIndex
Dim
iteration
As
Integer
= 0
For
Each
my2GroupInfo
In
aryGroupInfo
If
my2GroupInfo.strucHeaderGroupIndex.Equals(footerGroupIndex)
Then
my2GroupInfo.strucFooterIndex = index
aryGroupInfo.RemoveAt(iteration)
aryGroupInfo.Add(my2GroupInfo)
Exit
For
End
If
iteration += 1
Next
Next
'Now that we have matching Header and Footer information, we cycle
'through the arraylist we built above and use the index information
'to pull the appropriate counts from footer and append it to the
'header text.
For
index
As
Integer
= 0
To
headerSize - 1
Dim
my3GroupInfo
As
GroupInfo = aryGroupInfo.Item(index)
Dim
groupFooterItem
As
GridItem = TryCast(footerItems(my3GroupInfo.strucFooterIndex), GridItem)
Dim
groupHeaderItem
As
GridItem = TryCast(headerItems(my3GroupInfo.strucHeaderIndex), GridItem)
Dim
myFooterItem
As
GridGroupFooterItem = TryCast(groupFooterItem, GridGroupFooterItem)
Dim
myHeaderItem
As
GridGroupHeaderItem = TryCast(groupHeaderItem, GridGroupHeaderItem)
'The first group is set up on page load and I just wanted it to be a little
'different from the sub-groups in formatting. Therefore I looked to see if
'the GroupIndex contains a "_" (only the first group has that, all sub-groups
'have a GroupIndex like "x_y"). So if there is no "_", I give it my main group
'format. The same thing can be done for subsequent groups using substring to
'pull the "x" value and identify what sub-group you are in, but for our
'purposes, this was not necessary.
If
Not
myHeaderItem.GroupIndex.Contains(
"_"
)
Then
Dim
count
As
String
= myFooterItem(
"FullLnID"
).Text.Substring(7)
myHeaderItem.DataCell.Text = myHeaderItem.DataCell.Text &
" ( records: "
& count &
" )"
Else
Dim
count
As
String
= myFooterItem(
"FullLnID"
).Text.Substring(7)
myHeaderItem.DataCell.Text = myHeaderItem.DataCell.Text &
" ( Sub-group records: "
& count &
" )"
End
If
'We do not want to see the footer, since all we care about is a record count
'and we put it in the header. That said, it was necessary to include the
'footer to get the aggregate for the sub-groups so we needed it up to this
'point.
myFooterItem.Visible =
False
Next
Again, I hope this helps anyone trying to do the same thing.
It is good to see that you got the desired result. And thank you for sharing your findings with the community. Do not hesitate to post again in case any issues with this approach arise in the future.
Kind regards,
Tsvetina
the Telerik team