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
>