Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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);
        }