The story began by posing the problem of printing a ListView in such a way that the printing process takes into account the pagination. Although, WPF has the capability of printing any Visual, however it does nothing about pagination. It means if the visual exceeds one page, the over headed area would be excluded from the printed version. In the first part of this series, I showed an approach for the problem using custom DocumentPaginator. DocumentPaginator provides an abstract base class that supports creation of multiple-page elements from a single document. My custom DocumentPaginator created a ListView per page and then filled it by the ItemsSource of the original ListView until its size reached the end of the page. Filling the next page was started from the end position of the previous ListView. This process repeats until there is no data in the ItemsSource. Interested reader can read the first part of this series for further detail.
In the second part of this series, I extended the approach to support grouping of data. The proposed method used the GroupDescription class of the .net framework to define custom groups on the data. The generated groups can have Headers, Footers, PageHeaders and PageFooters. User is able to provide custom footers or headers using DataTemplates. Limiting to one group section is the main restriction of the previous version.
In this paper, I will expand the previous implementation to cover more complicated problems. The new implementation looks like a real report engine that covers almost 80% of the print requirements except charting and graphing. The new code involves lots of refactoring. The benefits of the new version can be summarized as follows:
- The ability to view the reports in a ReportViewer.
- The ability to define custom layouts for the reports including any number of groups, sub groups and etc..
- Simplifying the code by removing code redundancies.
- The ability to view the reports as XPS documents.
- The ability to dynamically deploy the reports.