This is a migrated thread and some comments may be shown as answers.

Aggregate lost on GroupsChanging event

11 Answers 223 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Victor
Top achievements
Rank 1
Victor asked on 08 Mar 2011, 10:47 PM

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

Sort by
0
Tsvetina
Telerik team
answered on 14 Mar 2011, 09:21 AM
Hi Victor,

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
Registration for Q1 2011 What’s New Webinar Week is now open. Mark your calendar for the week starting March 21st and book your seat for a walk through all the exciting stuff we ship with the new release!
0
Victor
Top achievements
Rank 1
answered on 14 Mar 2011, 01:35 PM

<%@ 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">
  
<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

0
Tsvetina
Telerik team
answered on 17 Mar 2011, 01:53 PM
Hi Victor,

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
0
Victor
Top achievements
Rank 1
answered on 17 Mar 2011, 02:13 PM
Hello,

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.

0
Tsvetina
Telerik team
answered on 22 Mar 2011, 03:48 PM
Hello Victor,

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
0
Victor
Top achievements
Rank 1
answered on 22 Mar 2011, 04:56 PM
Hello,

 

 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.
0
Tsvetina
Telerik team
answered on 28 Mar 2011, 09:58 AM
Hello Victor,

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
0
Victor
Top achievements
Rank 1
answered on 28 Mar 2011, 08:43 PM
Hello again,

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
0
Victor
Top achievements
Rank 1
answered on 29 Mar 2011, 02:24 PM
Hello,

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.
0
Victor
Top achievements
Rank 1
answered on 30 Mar 2011, 02:25 PM
Hello,

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.
0
Tsvetina
Telerik team
answered on 31 Mar 2011, 02:24 PM
Hello Victor,

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
Tags
Grid
Asked by
Victor
Top achievements
Rank 1
Answers by
Tsvetina
Telerik team
Victor
Top achievements
Rank 1
Share this question
or