/// <summary> /// Calculates the aggregates. /// </summary> /// <param name="aggregateDefinitions">The aggregate definitions.</param> /// <param name="sourceQueryCriteria">The query criteria.</param> /// <returns>An observable collection of aggregate results.</returns> public static async Task<AggregateResultCollection> CalculateAggregatesAsync(IList<AggregateDefinition> aggregateDefinitions, AggregateDataSourceQueryCriteria sourceQueryCriteria) { if (sourceQueryCriteria == null || aggregateDefinitions == null || !aggregateDefinitions.Any()) { return AdjustAggregateResults(new AggregateResultCollection(), aggregateDefinitions); } var criteria = BuildAggregateCriteria(aggregateDefinitions, sourceQueryCriteria); var result = await AggregateCommand.ExecuteAsync(criteria); return AdjustAggregateResults(result, aggregateDefinitions); }
/// <summary> /// Builds an <c>AggregateCriteria</c> object. /// </summary> /// <param name="aggregateDefinitions">The collection of aggregate definitions.</param> /// <param name="sourceQueryCriteria">The data source query criteria.</param> /// <returns>Cebos.Veyron.SharedTypes.AggregateCriteria</returns> private static AggregateCriteria BuildAggregateCriteria(IEnumerable<AggregateDefinition> aggregateDefinitions, AggregateDataSourceQueryCriteria sourceQueryCriteria) { var criteria = new AggregateCriteria { ProcessName = sourceQueryCriteria.ProcessName, PageNumber = sourceQueryCriteria.PageNumber, PageSize = sourceQueryCriteria.PageSize, GroupColumn = sourceQueryCriteria.GroupColumn, SecurityColumns = sourceQueryCriteria.SecurityColumns != null ? new MobileList<SecurityColumnDescriptor>(sourceQueryCriteria.SecurityColumns) : null, Sortings = sourceQueryCriteria.Sortings, FilterId = sourceQueryCriteria.FilterId, FilterDefinition = sourceQueryCriteria.FilterDefinition, QuickFilterString = sourceQueryCriteria.QuickFilterString }; var definitionsByColumn = new Dictionary<string, List<AggregateDefinition>>(); foreach (var def in aggregateDefinitions) { List<AggregateDefinition> defList; if (!definitionsByColumn.TryGetValue(def.ColumnName, out defList)) definitionsByColumn[def.ColumnName] = defList = new List<AggregateDefinition>(); defList.Add(def); } foreach (var columnInfo in definitionsByColumn) { var aggregates = columnInfo.Value; var columnItem = new AggregateColumnItem { ColumnName = columnInfo.Key, CustomConverter = aggregates[0].CustomConverter, TargetType = aggregates[0].TargetType, TypeName = aggregates[0].TypeName, ConverterParameter = aggregates[0].ConverterParameter }; foreach (var aggrDef in aggregates) { columnItem.AggregatesEnabled.Add( new AggregateTypeInfo { SummaryType = aggrDef.SummaryType }); } criteria.Columns.Add(columnItem); } return criteria; }
/// <summary> /// Creates the aggregate items. /// </summary> /// <param name="currentReport">The current report.</param> /// <param name="forGroups">if set to <c>true</c> [for groups].</param> /// <returns>List{TextBox}.</returns> private List<TextBox> CreateAggregateItems(Report currentReport, bool forGroups) { var height = new Unit(16); var aggregateItems = new Dictionary<string, List<TextBox>>(); var additionalInfoForLastAggregateItem = new Dictionary<Unit, float>(); //calculate server-side aggregates var aggregateDefinitions = _aggregateDict.ToList() .SelectMany(i => i.Value) .Where(d => !AggregateHelper.IsPageAggregateType(d.SummaryType)) .ToList(); var queryCriteria = new AggregateDataSourceQueryCriteria { ProcessName = _processName, FilterDefinition = GetFilterDefinition(currentReport) }; var serverAggregateResults = AggregateProcessor.CalculateAggregates(aggregateDefinitions, queryCriteria); foreach (var aggregateInfo in _aggregateDict) { var col = _colDict.FirstOrDefault(x => x.Value[0] == aggregateInfo.Key); if (!col.Equals(default(KeyValuePair<int, string[]>))) { var fieldValueMap = ((TextBox)currentReport.Items["detail"].Items["rowPanel"].Items[col.Key - 1]).Value.TrimStart('='); var locationX = ((TextBox)currentReport.Items["detail"].Items["rowPanel"].Items[col.Key - 1]).Location.X; var width = GetWidth(currentReport, aggregateInfo); var locationY = new Unit(0, locationX.Type); var list = new List<TextBox>(); foreach (var criteria in aggregateInfo.Value) { var textbox = new TextBox(); textbox.Style.Padding.Left = new Unit(1); textbox.Style.Padding.Right = new Unit(1); textbox.Style.Font.Size = new Unit(9); textbox.Style.Font.Name = "Arial Unicode MS"; textbox.Style.VerticalAlign = VerticalAlign.Middle; textbox.Size = new SizeU(Unit.Inch(width), height); textbox.CanGrow = true; textbox.TextWrap = true; textbox.Location = new PointU(locationX, locationY); if (_aggregateDict.Last().Equals(aggregateInfo)) { EventHandler textboxItemDataBoundHandler = (s, e) => { var ft = new FormattedText((string)((Telerik.Reporting.Processing.TextBox)s).Value, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface(new System.Windows.Media.FontFamily(((Telerik.Reporting.Processing.VisualElement)s).Style.Font.Name), new System.Windows.FontStyle(), new FontWeight(), new FontStretch()), ((Telerik.Reporting.Processing.VisualElement)s).Style.Font.Size.Value, System.Windows.Media.Brushes.Black); if (ft.Width > ((Telerik.Reporting.Processing.TextBox)s).Size.Width.Value) { foreach (var f in additionalInfoForLastAggregateItem) { ((Telerik.Reporting.Processing.ReportItem)s).Location = new PointU(f.Key, ((Telerik.Reporting.Processing.ReportItem)s).Location.Y); ((Telerik.Reporting.Processing.ReportItem)s).Size = new SizeU(Unit.Inch(f.Value + ((Telerik.Reporting.Processing.ReportItem)s).Size.Width.Value), height); if (((Telerik.Reporting.Processing.ReportItem)s).Size.Width.Value >= ft.Width) { break; } } } }; textbox.ItemDataBound += textboxItemDataBoundHandler; EventHandler textboxDisposedHandler = null; textboxDisposedHandler = (sender, args) => { textbox.ItemDataBound -= textboxItemDataBoundHandler; textbox.Disposed -= textboxDisposedHandler; }; textbox.Disposed += textboxDisposedHandler; } if (AggregateHelper.IsPageAggregateType(criteria.SummaryType)) { var aggregateFunction = forGroups ? "Exec" : "PageExec"; var aggregateFunctionParameter = forGroups ? ":scope:" : aggregateInfo.Key + "TextBox"; textbox.Value = string.Format( @"='{0}: ' + AfterCalculateAggregates({7}('{8}', {2}(BeforeCalculateAggregates(Fields.[{1}], ""{2}"", ""{3}"", ""{4}"", ""{5}"", ""{6}""))), ""{2}"", ""{3}"", ""{4}"", ""{5}"", ""{6}"")", AggregateHelper.GetAttribute(criteria.SummaryType).ShortName, aggregateInfo.Key, criteria.SummaryType, criteria.CustomConverter, criteria.TargetType, criteria.TypeName, criteria.ConverterParameter, aggregateFunction, aggregateFunctionParameter); } else { var result = serverAggregateResults.FirstOrDefault(r => r.ColumnName == criteria.ColumnName && r.SummaryType == criteria.SummaryType); textbox.Value = string.Format("{0}: {1}", AggregateHelper.GetAttribute(criteria.SummaryType).ShortName, result); } list.Add(textbox); locationY += height; } aggregateItems.Add(aggregateInfo.Key, list); } } if (aggregateItems.Count > 1) { var lastItem = aggregateItems.Last(); aggregateItems.Remove(lastItem.Key); var penultimateItem = aggregateItems.Last(); var indexOfPenultimateItem = _colDict.First(x => x.Value[0] == penultimateItem.Key).Key; var indexOfLastItem = _colDict.First(x => x.Value[0] == lastItem.Key).Key; if (indexOfLastItem - indexOfPenultimateItem > 1) // if exists at least one column between last and penultimate aggregate columns { // fill additional info for last aggrigate item var i = Convert.ToInt32((indexOfLastItem - indexOfPenultimateItem - 1) / 2); foreach (var column in _colDict) { if (column.Key >= i + indexOfPenultimateItem + 1 && column.Value[0] != lastItem.Key) { var item = ((ReportItem)currentReport.Items["detail"].Items["rowPanel"].Items.FirstOrDefault(x => x.Name == string.Format("{0}TextBox", column.Value[0]))); if (item != null) { additionalInfoForLastAggregateItem.Add(item.Location.X, item.Size.Width.Value); } } } var descending = additionalInfoForLastAggregateItem.Reverse(); additionalInfoForLastAggregateItem = descending.ToDictionary(x => x.Key, x => x.Value); // new size of penultimate item foreach (var textbox in penultimateItem.Value) { textbox.Size = new SizeU(Unit.Inch(textbox.Size.Width.Value / 2), height); } } aggregateItems.Add(lastItem.Key, lastItem.Value); } var returnList = new List<TextBox>(); foreach (var aggregateItem in aggregateItems) { returnList.AddRange(aggregateItem.Value); } return returnList; }
/// <summary> /// Builds the report. /// </summary> /// <param name="reportDocument">The report document.</param> public void BuildReport(ICustomReport reportDocument) { var currentReport = reportDocument.Reports.First(); SetIdentity(currentReport); //_originalPageHeaderHeight = ((PageHeaderSection) currentReport.Items["pageHeader"]).Height; //This report parameter holds the current template system name. _processName = currentReport.ReportParameters["processName"].Value.ToString(); //This report parameter holds the currently visible columns of the grid and in what order they're in var cols = currentReport.ReportParameters["columns"].Value.ToString(); var columns = cols.Split(';').ToList(); _columns = new List<ColumnInfo>(); foreach (var col in columns) { _columns.Add(new ColumnInfo(col)); } var groupsStr = currentReport.ReportParameters["groups"].Value.ToString(); _groups = (string.IsNullOrEmpty(groupsStr) ? new string[0] : groupsStr.Split(';')).ToList(); //TODO: Uncomment if needed // _columns.AddRange(_groups); if (reportDocument.FitToPage) { if (currentReport.GetType().Name.ToLower().Contains("landscape")) { FitToPageColumnWidth = Math.Min(1, 10.0 / _columns.Count); FitToPageColumnCount = (short) Math.Max(10, _columns.Count); } if (currentReport.GetType().Name.ToLower().Contains("portrait")) { FitToPageColumnWidth = Math.Min(1.1, 7.0 / _columns.Count); FitToPageColumnCount = (short) Math.Max(7, _columns.Count); } currentReport.Width = new Unit(_columns.Count * FitToPageColumnWidth, UnitType.Inch); } _groupColumn = currentReport.ReportParameters["groupColumn"].Value.ToString(); var fldList = new List<FieldInfo>(_columns.Count); var processProperties = new Dictionary<PropertyInfo, string>(); var processType = TheDynamicTypeManager.GetInfoType<IInfoClass>(_processName); if (processType != null) { processProperties = processType.GetAllPropertiesWithPaths(); var properties = processProperties.Where(p => _columns.Any(c=>c.SystemName == p.Value)); foreach (var column in _columns) { foreach (var property in properties) { if (property.Value == column.SystemName) { fldList.Add(new FieldInfo(property.Key, column)); break; } } } _fieldAttrDict = GetFieldAttributes(processProperties.Select(x => x.Key)); } if (_fieldAttrDict == null) _fieldAttrDict = new Dictionary<PropertyInfo, FieldParametres>(); _colDict = new SortedDictionary<int, string[]>(); //Grouping foreach (var colName in _groups) { var group = new Telerik.Reporting.Group(); group.Name = colName; var groupHeaderSection = new GroupHeaderSection(); var groupFooterSection = new GroupFooterSection(); group.GroupHeader = groupHeaderSection; group.GroupFooter = groupFooterSection; var txt = new TextBox(); txt.Style.Font.Size = new Unit(10, UnitType.Point); txt.Style.Font.Bold = true; txt.Style.BackgroundColor = Color.FromArgb(255, 225, 225, 225); txt.Style.TextAlign = HorizontalAlign.Left; txt.Style.VerticalAlign = VerticalAlign.Middle; groupHeaderSection.Items.Add(txt); groupHeaderSection.Height = new Unit(21); groupHeaderSection.Style.BorderStyle.Default = BorderType.Solid; groupHeaderSection.Style.BorderColor.Default = Color.White; groupHeaderSection.Style.BorderColor.Left = Color.Transparent; var panel = new Panel(); panel.Height = new Unit(20); panel.Style.LineStyle = LineStyle.Solid; panel.Style.LineWidth = new Unit(2.0); panel.Style.BorderColor.Default = Color.Black; panel.Style.BorderWidth.Default = new Unit(2.0); panel.Style.BorderStyle.Default = BorderType.None; panel.Style.BorderStyle.Top = BorderType.Solid; panel.Style.BorderStyle.Bottom = BorderType.Solid; groupFooterSection.Items.Add(panel); groupFooterSection.Height = new Unit(25); //groupFooterSection.Style.BorderStyle.Default = BorderType.Solid; //groupFooterSection.Style.BorderColor.Default = Color.White; groupFooterSection.Style.BorderColor.Left = Color.Transparent; groupFooterSection.Style.Padding.Top = new Unit(2); groupFooterSection.Style.Padding.Bottom = new Unit(2); //if you need to filter the data, apply filtering //group1.Filters.Add(new Telerik.Reporting.Data.Filter("=Fields.ProductID", Telerik.Reporting.Data.FilterOperator.Equal, "=10")); currentReport.Groups.Add(group); } var aggregateData = currentReport.ReportParameters["aggregates"].Value.ToString(); _aggregateDict = ParseAggregateData(aggregateData); var nextLeft = _groups.Count > 0 ? (_groups.Count - 1) * 0.15 : 0; var availableWidth = currentReport.Width.Value - nextLeft; var ctrlSize = availableWidth / (fldList.Count() - _groups.Count); _indentOffset = 0; _reportItemCounter = new Dictionary<string, int>(); var counter = 0; double fitToPageFooterLocationX = 0; //posess fields foreach (var fld in fldList) { if (_reportItemCounter.ContainsKey(fld.Property.Name)) { continue; } var fieldValueMap = GetFieldValueMap(currentReport, fld.Property, processProperties[fld.Property]); if (_groups.Contains(processProperties[fld.Property] ?? string.Empty)) { //create group var fieldGroup = currentReport.Groups.FirstOrDefault(x => x.Name == processProperties[fld.Property]); if (fieldGroup != null) { _indentOffset = 0.15 * _groups.IndexOf(processProperties[fld.Property]); fieldGroup.Groupings.Add(new Grouping(fieldValueMap)); ((TextBox)fieldGroup.GroupHeader.Items[0]).Value = string.Format("=' ' + {0} + ' Total: ' + Exec('{1}', Count(IsNull({0},1)))", fieldValueMap.TrimStart('='), fieldGroup.Name); ((TextBox)fieldGroup.GroupHeader.Items[0]).Location = new PointU(new Unit(_indentOffset, UnitType.Inch), new Unit(0, UnitType.Inch)); ((TextBox)fieldGroup.GroupHeader.Items[0]).Size = new SizeU(new Unit(currentReport.Width.Value - _indentOffset, UnitType.Inch), new Unit(20, UnitType.Pixel)); //AddGroupLevelLines(fieldGroup.GroupHeader.Items); ((Panel)fieldGroup.GroupFooter.Items[0]).Location = new PointU(new Unit(_indentOffset, UnitType.Inch), new Unit(0, UnitType.Inch)); ((Panel)fieldGroup.GroupFooter.Items[0]).Size = new SizeU(new Unit(currentReport.Width.Value - _indentOffset, UnitType.Inch), new Unit(20, UnitType.Pixel)); //AddGroupLevelLines(fieldGroup.GroupFooter.Items); } continue; } var cPoint = new PointU(new Unit(nextLeft, UnitType.Inch), new Unit(0.4, UnitType.Inch)); var uSize = new SizeU(new Unit(ctrlSize, UnitType.Inch), new Unit(0.2, UnitType.Inch)); var attr = fld.Property.GetCustomAttributes(false); var displayAttr = attr.FirstOrDefault(x => x is DisplayAttribute) as DisplayAttribute; string colName = "<NoName>"; if (displayAttr == null) { colName = fld.Column.Header; //var infoInstance = Activator.CreateInstance(processType); //if (infoInstance != null) //{ // var field = processType.GetField(fld.Name + "Property"); // if (field != null) // { // var fieldValue = field.GetValue(infoInstance) as IPropertyInfo; // if (fieldValue != null) // { // colName = fieldValue.FriendlyName; // } // } //} } else { colName = displayAttr.GetName(); } var headerLabel = new TextBox { Value = colName, Location = cPoint, Size = uSize, StyleName = "Caption", Multiline = true, CanGrow = true }; headerLabel.Style.BackgroundColor = Color.Transparent; headerLabel.Style.Font.Size = new Unit(10, UnitType.Point); headerLabel.Style.VerticalAlign = VerticalAlign.Top; var dataTextBox = new TextBox(); var dataTextBoxName = string.Format("{0}TextBox", processProperties[fld.Property]); dataTextBox.Name = dataTextBoxName; var propertyName = processProperties[fld.Property]; var isExistsBackgroudColor = processProperties.Any(x => x.Key.Name == propertyName + Constants.FieldBackColorPostfix); dataTextBox.TextWrap = true; dataTextBox.Location = new PointU(new Unit(nextLeft, UnitType.Inch), new Unit(0, UnitType.Inch)); dataTextBox.Size = uSize; dataTextBox.CanGrow = true; if (isExistsBackgroudColor) { if (fieldValueMap.StartsWith("=")) { fieldValueMap = fieldValueMap.Remove(0, 1); fieldValueMap = string.Format("=GetValueWithBackgroundColor({0}, Fields.[{1}{2}])", fieldValueMap, processProperties[fld.Property], Constants.FieldBackColorPostfix); EventHandler itemDataBoundHandler = (sender, args) => { var textBox = sender as Telerik.Reporting.Processing.TextBox; if (textBox == null) { return; } var colorAsLong = ((KeyValuePair<object, long>)textBox.Value).Value; if (colorAsLong != 0) { var bytes = BitConverter.GetBytes(colorAsLong); if (bytes[3] == 0) bytes[3] = 255; var color = Color.FromArgb(bytes[3], bytes[2], bytes[1], bytes[0]); ((Telerik.Reporting.Processing.ProcessingElement)sender).Style.BackgroundColor = color; } textBox.Value = ((KeyValuePair<object, long>)textBox.Value).Key; }; dataTextBox.ItemDataBound += itemDataBoundHandler; EventHandler dataTextBoxDisposedHandler = null; dataTextBoxDisposedHandler = (sender, args) => { dataTextBox.ItemDataBound -= itemDataBoundHandler; dataTextBox.Disposed -= dataTextBoxDisposedHandler; }; dataTextBox.Disposed += dataTextBoxDisposedHandler; } } dataTextBox.Value = fieldValueMap; if (!reportDocument.FitToPage) { dataTextBox.ItemDataBound += OnItemDataBound; EventHandler dataTextBoxDisposedHandler = null; dataTextBoxDisposedHandler = (sender, args) => { dataTextBox.ItemDataBound -= OnItemDataBound; dataTextBox.Disposed -= dataTextBoxDisposedHandler; }; dataTextBox.Disposed += dataTextBoxDisposedHandler; } var pictureBox = new PictureBox { Value = fieldValueMap }; pictureBox.Name = string.Format("{0}TextBox", processProperties[fld.Property]); pictureBox.Sizing = ImageSizeMode.ScaleProportional; if (!reportDocument.FitToPage) { pictureBox.ItemDataBound += OnItemDataBound; EventHandler pictureBoxDisposedHandler = null; pictureBoxDisposedHandler = (sender, args) => { pictureBox.ItemDataBound -= OnItemDataBound; pictureBox.Disposed -= pictureBoxDisposedHandler; }; pictureBox.Disposed += pictureBoxDisposedHandler; } nextLeft = nextLeft + ctrlSize; if (reportDocument.FitToPage) { currentReport.Items["labelsGroupHeaderSection"].Items.Add(headerLabel); } else { currentReport.Items["pageHeader"].Items.Add(headerLabel); } if (_fieldAttrDict[fld.Property].FieldEditor == "Image") { currentReport.Items["detail"].Items["rowPanel"].Items.Add(pictureBox); } else { currentReport.Items["detail"].Items["rowPanel"].Items.Add(dataTextBox); } _reportItemCounter.Add(processProperties[fld.Property], 0); if (reportDocument.FitToPage) { _colDict.Add(currentReport.Items["labelsGroupHeaderSection"].Items.Count - 1, new[] { processProperties[fld.Property], headerLabel.Value }); } else { _colDict.Add(currentReport.Items["pageHeader"].Items.Count - 1, new[] { processProperties[fld.Property], headerLabel.Value }); } if (reportDocument.FitToPage) { fitToPageFooterLocationX = counter % FitToPageColumnCount == 0 ? 0 : fitToPageFooterLocationX; if (_aggregateDict.Keys.All(x => x != fld.Property.Name)) { var footerTextBox = new TextBox { Name = string.Format("{0}{1}FooterTextBox", fld.Property.Name, fldList.IndexOf(fld)), Location = new PointU(new Unit(fitToPageFooterLocationX, UnitType.Inch), new Unit(0, UnitType.Inch)), Size = new SizeU(new Unit(FitToPageColumnWidth, UnitType.Inch), new Unit(0.15, UnitType.Inch)) }; currentReport.Items["pageFooter"].Items.Add(footerTextBox); } //calculate server-side aggregates var aggregateDefinitions = _aggregateDict.ToList() .SelectMany(i => i.Value) .Where(d => !AggregateHelper.IsPageAggregateType(d.SummaryType)) .ToList(); var queryCriteria = new AggregateDataSourceQueryCriteria { ProcessName = _processName, FilterDefinition = GetFilterDefinition(currentReport) }; var serverAggregateResults = AggregateProcessor.CalculateAggregates(aggregateDefinitions, queryCriteria); foreach (var aggregateItem in _aggregateDict) { if (aggregateItem.Key != fld.Property.Name) { continue; } double fitToPageFooterLocationY = 0; for (var i = 0; i < aggregateItem.Value.Count; i++) { var footerTextBox = new TextBox { Name = string.Format("{0}{1}FooterTextBox", fld.Property.Name, aggregateItem.Value[i].SummaryType), // telerik recommends set unique names for all controls Size = new SizeU(new Unit(GetWidthFitToPage(fld.Property.Name, i), UnitType.Inch), new Unit(0.15, UnitType.Inch)), Location = new PointU(new Unit(fitToPageFooterLocationX, UnitType.Inch), new Unit(fitToPageFooterLocationY, UnitType.Inch)) }; if (AggregateHelper.IsPageAggregateType(aggregateItem.Value[i].SummaryType)) { footerTextBox.Value = string.Format(@"='{0}: ' + AfterCalculateAggregates(PageExec('{1}TextBox', {2}(BeforeCalculateAggregates(Fields.[{1}], ""{2}"", ""{3}"", ""{4}"", ""{5}"", ""{6}""))), ""{2}"", ""{3}"", ""{4}"", ""{5}"", ""{6}"")", AggregateProcessor.GetAggregateFunctionShortName(aggregateItem.Value[i].SummaryType), aggregateItem.Key, aggregateItem.Value[i].SummaryType, aggregateItem.Value[i].CustomConverter, aggregateItem.Value[i].TargetType, aggregateItem.Value[i].TypeName, aggregateItem.Value[i].ConverterParameter); } else { var result = serverAggregateResults.FirstOrDefault(r => r.ColumnName == aggregateItem.Key && r.SummaryType == aggregateItem.Value[i].SummaryType); footerTextBox.Value = string.Format("{0}: {1}", AggregateHelper.GetAttribute(aggregateItem.Value[i].SummaryType).ShortName, result != null ? result.Value : Constants.Empty); } if (aggregateItem.Value[i].SummaryType == SummaryTypes.Count) { footerTextBox.Bindings.Add(new Binding("Visible", string.Format(@"=IIf(PageExec(""{0}"", Count(Fields.{1})) = 0, False, True)", dataTextBoxName, fld.Property.Name))); } if (aggregateItem.Value[i].SummaryType == SummaryTypes.Min || aggregateItem.Value[i].SummaryType == SummaryTypes.Max) { if (fld.Property.PropertyType != typeof(bool) && fld.Property.PropertyType != typeof(bool?))//VRN-5079 { footerTextBox.Bindings.Add(new Binding("Visible", string.Format(@"=FooterTextBoxVisibilityWithValue(PageExec(""{0}"", Min(Fields.{1})))", dataTextBoxName, fld.Property.Name))); } } fitToPageFooterLocationY += 0.15; currentReport.Items["pageFooter"].Items.Add(footerTextBox); } } fitToPageFooterLocationX += FitToPageColumnWidth; counter++; } } if (reportDocument.FitToPage) { var max = _aggregateDict.Count == 0 ? 0 : _aggregateDict.Max(x => x.Value.Count); if (max != 0) { ((PageFooterSection) currentReport.Items["pageFooter"]).Height = new Unit(max*0.15 + 0.2, UnitType.Inch); } currentReport.Items["pageFooter"].Items["currentTimeTextBox"].Visible = false; currentReport.Items["pageFooter"].Items["pageInfoTextBox"].Visible = false; } _indentOffset = _groups.Count > 0 ? (_groups.Count - 1) * 0.15 : 0; //AddGroupLevelLines(currentReport.Items["detail"].Items["rowPanel"].Items); }