ASP.NET setting "ColSpan" breaks table layout with fixed columns by overriding RenderContents
This is an interesting problem.
If you have a table where you have very long words you find that rather than breaking the words the browser resizes the table so it flows off the page.
This is quite simple to fix by adding the following CSS to the table
table-layout: fixed;
word-wrap: break-word;
And setting a fixed size to the first column using a standard style="width:200px;" for example.
The very long words are then broken appropriately. Very nice
What happens however when you add a title row to the table (using a <Row ColSpan="2"> for example) is that the table ignored the width declarations for the subsequent rows because when using a fixed layout the width of the columns in the first row is consulted. The first column then sizes itself automatically. In the screenshot you can see if resizes to around 50% of the browser window as the browser is resized.
To solve this in HTML is quite simple by using <col> definitions to inform the table "upfront" what widths to use for the columns rather than looking at the first row.
<table>
<col style="width:200px;">
<col >
</table>
The problem in ASP.NET is that the Table class does not support column definitions however you can add them by overriding the RenderContents(HtmlTextWriter writer) method.
In the following example (which does need some polishing) we enumerate the rows in the table and find the first row that isn't a header row (by checking for cells that have a ColSpan of greater than 1).
We then use this "normal" row to set the column definitions for the table automatically. It would perhaps be nicer to add a "ColumnDefinitions" property to the table and explicitly set the column definitions rather than dynamically detecting them.
If you have a table where you have very long words you find that rather than breaking the words the browser resizes the table so it flows off the page.
This is quite simple to fix by adding the following CSS to the table
table-layout: fixed;
word-wrap: break-word;
And setting a fixed size to the first column using a standard style="width:200px;" for example.
The very long words are then broken appropriately. Very nice
What happens however when you add a title row to the table (using a <Row ColSpan="2"> for example) is that the table ignored the width declarations for the subsequent rows because when using a fixed layout the width of the columns in the first row is consulted. The first column then sizes itself automatically. In the screenshot you can see if resizes to around 50% of the browser window as the browser is resized.
To solve this in HTML is quite simple by using <col> definitions to inform the table "upfront" what widths to use for the columns rather than looking at the first row.
<table>
<col style="width:200px;">
<col >
</table>
The problem in ASP.NET is that the Table class does not support column definitions however you can add them by overriding the RenderContents(HtmlTextWriter writer) method.
In the following example (which does need some polishing) we enumerate the rows in the table and find the first row that isn't a header row (by checking for cells that have a ColSpan of greater than 1).
We then use this "normal" row to set the column definitions for the table automatically. It would perhaps be nicer to add a "ColumnDefinitions" property to the table and explicitly set the column definitions rather than dynamically detecting them.
/// <summary>
/// Provides additional functionality over the
standard table, allowing column definitions to be set on the table.
/// </summary>
/// <remarks>This is a workaround for the issue that
the first column width isn't honoured when a title row is found in the table.</remarks>
public class PropertyGridTable:Table
{
/// <summary>
/// Renders the contents of
the table.
/// </summary>
/// <param name="writer">The System.Web.UI.HtmlTextWriter to which the content is
written.</param>
protected override void RenderContents(HtmlTextWriter
writer)
{
WriteColumnDefinitions(writer);
base.RenderContents(writer);
}
/// <summary>
/// Adds the column
definitions if required.
/// </summary>
/// <param name="writer">The System.Web.UI.HtmlTextWriter to which the content is
written.</param>
private void
WriteColumnDefinitions(HtmlTextWriter
writer)
{
bool SizeRow = true;
foreach (TableRow
Row in Rows)
{
SizeRow = true;
foreach (TableCell
Cell in Row.Cells)
{
if (Cell.ColumnSpan > 1) { SizeRow = false; continue; }
}
if (SizeRow)
{
foreach (TableCell
Cell in Row.Cells)
{
if (Cell.Width.Value > 0) {
writer.AddAttribute("Width",
Cell.Width.ToString()); }
if (!String.IsNullOrEmpty(Cell.Style["width"])) { writer.AddStyleAttribute("width", Cell.Style["width"]); }
writer.RenderBeginTag("Col");
writer.RenderEndTag();
}
return;
}
}
}
}
Comments
Post a Comment