In Telerik Reporting, the PageNumber object can only be used in the page header and page footer sections. It contains the current page number and its value is increased with one for every new page. In some scenarios, it is useful to alter the page number based on a condition and the most frequent scenario being asked is resetting the PageNumber after each group.

The powerful expression engine of Telerik Reporting allows you to accomplish this easily with the help of page aggregates and tiny bit of code.

Basically the idea is to check what is the last group on a page and if it has changed, then we reset the page number; otherwise simply advance the page counter.

In order to get the last group on the current page we need an expression like this:

=PageExec('detail', Last(Fields.ProductCategory))

which executes the Last() aggregate function against the data on the current page with the detail section being the scope (specified by the 1st argument of the PageExec function).

Having the last product category per page we need to perform a simple logic that will find if we are moving to a new group or keeping with the current. In order to avoid any concurrent issues we choose to persist the page calculation state in the current report instance. To do so we use instance function instead of the globally scoped static (Shared in VisualBasic.NET) functions:

namespace Telerik.Reporting.Examples.CSharp
{
    using Telerik.Reporting;
 
    /// <summary>
    /// Summary description for PageNumberTestReport.
    /// </summary>
    public partial class ResetPageNumberPerGroup : Telerik.Reporting.Report
    {
        public ResetPageNumberPerGroup()
        {
            InitializeComponent();
        }
 
        int currentPageNumber;
        string currentGroup;
         
        public int MyPageNumber(string lastGroupOnPage, int reportPageNumber)
        {
            if (null == lastGroupOnPage)
            {
                return this.currentPageNumber;
            }
 
            if (this.currentGroup != lastGroupOnPage || reportPageNumber == 1)
            {
                this.ResetPageNumbering(lastGroupOnPage);
            }
            else
            {
                this.NextPageNumber();
            }
 
            return this.currentPageNumber;
        }
 
        void ResetPageNumbering(string lastGroupOnPage)
        {
            this.currentPageNumber = 1;
            this.currentGroup = lastGroupOnPage;
        }
 
        void NextPageNumber()
        {
            this.currentPageNumber++;
        }
    }
}

 

Finally we combine the two parts in a single expression and display it in a TextBox:

=ReportItem.Report.ItemDefinition.MyPageNumber(PageExec("detail", Last(Fields.ProductCategory)), PageNumber)

where ReportItem.Report.ItemDefinition.MyPageNumber is the instance function we’ve already defined in our report definition.
You can use this expression instead of the built-in PageNumber object in page sections only.

Here is a screenshot from the sample project attached to this blog post that shows the “group” page number in the page header section (Orange) and the “report” page number in the page footer section (GreenYellow):  

reset page number


About the Author

Stefan Tsokev

Stefan’s main interests outside the .NET domain include rock music, playing the guitar and swimming.

Related Posts

Comments