private double GetIntersectOffset(double curOffset, double pageWidth) { //Gets the position of the Control to print on the screen var mainTranform = ControlToPrint.TransformToVisual(Application.Current.RootVisual); var mainOffset = mainTranform.Transform(new Point(0, 0)); //Creates a 1 pixel line where the control is going to be paginated var intersectRect = new Rect(mainOffset.X, curOffset + mainOffset.Y, pageWidth, 1); //This gets all controls that the intersectRect crosses that are inside of the ControlToPrint //The coordinates of the intersectRect must be relative to the whole screen not just the control itself //all the second parameter does is filter the elements that get returned. var elements = VisualTreeHelper.FindElementsInHostCoordinates(intersectRect, ControlToPrint); if (elements.Count() == 0) { _forceStopPagging = true; } var maxOffset = 0.0; foreach (var uiElement in elements) { ////Any control that can have children can be paginated (ie. Panels,ContentControls,ItemControls) ////Things that dont have children (ie textblock,textbox,Image) cannot be paginated if (VisualTreeHelper.GetChildrenCount(uiElement) <= 0) { ////TODO: possibly take into account other types of controls that can have children but are empty ////what if there is a stackpanel with no children but a hieght of 100, this makes no sense in a UI but it is possible if (uiElement is Border) { ////an empty border can be paginated continue; } //Make sure we have the corect size of the object being cut uiElement.Measure(new Size(pageWidth, double.MaxValue)); //Get the coordinates of the element with respect to the control being printed var gt = uiElement.TransformToVisual(ControlToPrint); var offset = gt.Transform(new Point(0, 0)); //Get the Height of the element that is left on the current page, this is used to know the adjustment needed to the overal offset var elementOffset = (curOffset + intersectRect.Height) - offset.Y; //Get the max of all controls that are being cut. maxOffset = Math.Max(maxOffset, elementOffset); } } return(maxOffset); }
private int GetTotalPages() { if (!_totalPages.HasValue) { _forceStopPagging = false; _coverOffsetCache.Clear(); var availableSizeOnPage = _printPage.GetHeightAvailable(); var pageWidth = _printPage.Width; //Calles measure to make sure we know the full height of the Control to Print ControlToPrint.Measure(new Size(pageWidth, double.MaxValue)); var controlHeight = ControlToPrint.DesiredSize.Height; var curOffset = availableSizeOnPage; var pageCount = 1; //Loops through control hieght to find how many pages there needs to be while (curOffset < controlHeight) { var coverOffset = GetIntersectOffset(curOffset, pageWidth); _coverOffsetCache.Add(pageCount, coverOffset); curOffset -= coverOffset; if (_forceStopPagging) { break; } pageCount++; curOffset += availableSizeOnPage; } if (!_forceStopPagging) { ////for last page, last page was already handled if pagginging was forcably stopped _coverOffsetCache.Add(pageCount, 0.0); } _totalPages = pageCount; } return(_totalPages.Value); }