/// <summary> /// Processes the section up to heightTreshold. /// </summary> /// <returns> /// returns <c>true</c> if finished processig section and <c>false</c> while not /// </returns> /// <param name='pageBreakTreshold'> /// maxiumum height (starting from current section Location.Y) after which page will break /// </param> public bool ProcessSectionUpToHeightTreshold(double heightTreshold) { double span = 0; double y = 0; double maxHeight = 0; double maxControlBottom = 0; double tmpSpan = 0; bool result = true; double realBreak = 0; double breakControlMax = 0; bool allKeepTogether = false; double heightTresholdIncludingBottomMargin = 0; if (currentSectionOrderedControls.Count > 0) { maxControlBottom = currentSectionOrderedControls.Max(ctrl => ctrl.Bottom); } marginBottom = currentSection.Height - maxControlBottom; heightTresholdIncludingBottomMargin = heightTreshold - marginBottom; for (int i = 0; i < currentSectionOrderedControls.Count; i++) { var control = currentSectionOrderedControls [i]; tmpSpan = double.MinValue; if (!control.IsVisible) { continue; } if (control is Line && (control as Line).ExtendToBottom) { var line = control as Line; currentSectionExtendedLines.Add(line); } if (source != null && control is IDataControl) { IDataControl dc = control as IDataControl; if (!string.IsNullOrEmpty(dc.FieldName)) { switch (dc.FieldKind) { case FieldKind.Parameter: if (parameters.ContainsKey(dc.FieldName)) { var parameter = parameters [dc.FieldName]; dc.Text = parameter.GetValue(parameter.DefaultValue, dc.FieldTextFormat); } break; case FieldKind.Expression: if (dc.FieldName == "#PageNumber") { dc.Text = context.CurrentPageIndex.ToString(); } else if (dc.FieldName == "#RowNumber") { dc.Text = context.RowIndex.ToString(); } break; case FieldKind.Data: if (source.ContainsField(dc.FieldName)) { dc.Text = source.GetValue(dc.FieldName, dc.FieldTextFormat); } break; default: break; } } } y = control.Top + span; Size controlSize = ReportRenderer.MeasureControl(control); foreach (SpanInfo item in currentSectionSpans) { if (y > item.Treshold) { tmpSpan = Math.Max(tmpSpan, item.Span); } } span = tmpSpan == double.MinValue ? 0 : tmpSpan; control.Top += span; if (control is SubReport) { SubReport sr = control as SubReport; double maxSubreportHeight = ((heightTreshold - span) - sr.Top); sr.ProcessUpToPage(this.ReportRenderer, maxSubreportHeight); if (!(sr.Engine.context.HeightUsedOnCurrentPage > maxSubreportHeight)) { controlSize = new Size(sr.Width, sr.Engine.context.HeightUsedOnCurrentPage); subreportSectionControlsBuffer.AddRange(sr.Engine.currentPage.Controls); sr.Engine.currentPage.Controls.Clear(); if (!sr.Finished && sr.CanGrow) { storeSectionForNextPage(); var subreportClone = sr.CreateControl() as SubReport; subreportClone.Top -= 0; subreportClone.Engine = sr.Engine; subreportClone.Height = sr.TemplateControl.Height; storeControlForNextSection(subreportClone); sr.Engine.nextPage(); } if (!sr.Finished) { result = false; } } else { Console.Write("error:"); } } double heightBeforeGrow = control.Height; double bottomBeforeGrow = control.Bottom; control.Size = controlSize; if (control.Bottom <= heightTreshold) { if (!allKeepTogether) { currentSectionControlsBuffer.Add(control); } else { storeSectionForNextPage(); var controlToStore = control; controlToStore.Top -= realBreak; controlToStore.Height = heightBeforeGrow; storeControlForNextSection(controlToStore); } } else { result = false; storeSectionForNextPage(); if (!currentSection.KeepTogether) { breakControlMax = control.Height - ((control.Top + control.Height) - heightTreshold); if (realBreak == 0) { realBreak = heightTreshold; } if (control.Top > heightTreshold) { var controlToStore = control.CreateControl(); controlToStore.Top -= realBreak; controlToStore.Height = heightBeforeGrow; storeControlForNextSection(controlToStore); continue; } Control[] brokenControl = ReportRenderer.BreakOffControlAtMostAtHeight(control, breakControlMax); realBreak = heightTreshold - (breakControlMax - brokenControl [0].Height); storeControlForNextSection(brokenControl [1]); currentSectionControlsBuffer.Add(brokenControl [0]); } else { var controlToStore = control; controlToStore.Top -= realBreak; controlToStore.Height = heightBeforeGrow; if (!allKeepTogether) { for (int w = 0; w < currentSectionControlsBuffer.Count; w++) { currentSectionControlsBuffer [w].Height = currentSectionControlsBuffer [w].TemplateControl.Height; controlsFromPreviousSectionPage [currentSection.Name].Add(currentSectionControlsBuffer [w]); } allKeepTogether = true; } storeControlForNextSection(controlToStore); continue; } } if (currentSection.CanGrow && maxHeight <= control.Bottom) { maxHeight = Math.Max(control.Bottom, maxHeight); } if (!result) { if (realBreak > 0) { maxHeight = Math.Max(realBreak, maxHeight); } } currentSectionSpans.Add( new SpanInfo { Treshold = bottomBeforeGrow, Span = span + control.Bottom - bottomBeforeGrow }); } double sectionHeightWithMargin = maxHeight + marginBottom; if (!result) { currentSection.Height = heightTreshold; } else if ((currentSection.CanGrow && currentSection.Height < sectionHeightWithMargin) || (currentSection.CanShrink && currentSection.Height > sectionHeightWithMargin)) { currentSection.Height = sectionHeightWithMargin; } else { currentSection.Height = Math.Min(currentSection.Height, heightTreshold); } foreach (Line lineItem in currentSectionExtendedLines) { if (lineItem.Location.Y == lineItem.End.Y) { lineItem.Location = new Point(lineItem.Location.X, currentSection.Height - lineItem.LineWidth / 2); lineItem.End = new Point(lineItem.End.X, currentSection.Height - lineItem.LineWidth / 2); } else if (lineItem.Location.Y > lineItem.End.Y) { lineItem.Location = new Point(lineItem.Location.X, currentSection.Height); } else { lineItem.End = new Point(lineItem.End.X, currentSection.Height); } if (!result) { var newCtrl = lineItem.CreateControl(); if (lineItem.Location.Y == lineItem.End.Y) { lineItem.IsVisible = false; } newCtrl.Top = 0; storeSectionForNextPage(); controlsFromPreviousSectionPage [currentSection.Name].Insert(1, newCtrl); } } sectionToStore = null; if (!currentSection.CanGrow) { controlsFromPreviousSectionPage.Remove(currentSection.Name); result = true; } return(result); }