When calculating width of the cell for export I was surprised when I discovered the following:
the handling of controls must be different when exporting to PDF and Excel
the handling of controls must be different when exporting to PDF and Excel
protected override void OnPreRender(EventArgs e) { base.OnPreRender(e); if (IsExport) { const int charWidth = 10; var gridWidth = 0; foreach (GridColumn column in MasterTableView.Columns) { if (column is GridEditableColumn) { var columnWidth = 0; var currentlyExportingTypes = column.CurrentFilterValue.GetTypesFromSeparatedString<DSExportType>(); if (currentlyExportingTypes.Count > 0 && !currentlyExportingTypes.Contains(_currentlyExportingType.Value) || column.HeaderText == "#" || column.UniqueName == "checker") { column.Visible = false; } if (column.Visible) { var alignmentCssClassPattern = new Regex("\\b(?<alignment>ca|la|ra)\\b"); var alignmentCssClassPatternMatch = alignmentCssClassPattern.Match(column.HeaderStyle.CssClass); foreach (GridDataItem dataItem in MasterTableView.Items) { var currentColumnWidth = 0; if (column is GridTemplateColumn) { int labelLengths; switch (_currentlyExportingType) { case DSExportType.Excel: labelLengths = (from label in dataItem[column.UniqueName].Controls.OfType<LiteralControl>().Where(label => !label.Text.StartsWith("\r\n")) select label.Text.Length).Sum(); currentColumnWidth = labelLengths * charWidth; break; case DSExportType.Pdf: labelLengths = (from label in dataItem[column.UniqueName].Controls.OfType<WebControl>().OfType<Label>() select label.Text.Length).Sum(); var hyperLinkLengths = (from hyperLink in dataItem[column.UniqueName].Controls.OfType<WebControl>().OfType<HyperLink>() select hyperLink.Text.Length).Sum(); var imageWidths = (from image in dataItem[column.UniqueName].Controls.OfType<WebControl>().OfType<Image>() select image.Width.Value).Sum(); currentColumnWidth = labelLengths * charWidth + hyperLinkLengths * charWidth + Convert.ToInt32(imageWidths); break; } } else { // Only for text types, should be check the type more carefully in common case! currentColumnWidth = dataItem[column.UniqueName].Text.Length * charWidth; } if (columnWidth < currentColumnWidth) { columnWidth = currentColumnWidth; } if (alignmentCssClassPatternMatch.Success) { switch (alignmentCssClassPatternMatch.Groups["alignment"].Value) { case "ca": dataItem[column.UniqueName].Style["text-align"] = "center"; break; case "ra": dataItem[column.UniqueName].Style["text-align"] = "right"; break; default: dataItem[column.UniqueName].Style["text-align"] = "left"; break; } } dataItem[column.UniqueName].Style.Add("white-space", "nowrap"); } foreach (GridHeaderItem headerItem in MasterTableView.GetItems(GridItemType.Header)) { if (alignmentCssClassPatternMatch.Success) { switch (alignmentCssClassPatternMatch.Groups["alignment"].Value) { case "ca": headerItem[column.UniqueName].Style["text-align"] = "center"; break; case "ra": headerItem[column.UniqueName].Style["text-align"] = "right"; break; default: headerItem[column.UniqueName].Style["text-align"] = "left"; break; } } } var finalColumnWidth = Math.Max(columnWidth, column.HeaderText.Length * charWidth); column.HeaderStyle.Width = Unit.Pixel(finalColumnWidth); gridWidth += finalColumnWidth; } } } ExportSettings.Pdf.PageWidth = Unit.Pixel(gridWidth + 2 * PdfGridPadding); _currentlyExportingType = null; } }The given method works, but the question is
why in the case of Excel export there is only LiteralControl within dataItem[column.UniqueName].Controls? Where is the image, for instance? I need different types of controls to properly calculate cell width.
But when I am on image column - dataItem[image_column_unique_name].Controls also returns me only LiteralControls and no any reference to the used image:
<telerik:GridTemplateColumn HeaderStyle-CssClass='GridHeaderGreen ra' ItemStyle-CssClass='ra' UniqueName="image_column_unique_name">
<ItemTemplate><asp:image runat="server" ImageUrl="~/images/something.png" /></ItemTemplate>
</telerik:GridTemplateColumn>