Reputation: 36896
I would like to create a user control which contains the following in the ASCX file:
...
<tr runat="server" ID="mytr">
<td runat="server" ID="myCell1"></td>
<asp:PlaceHolder runat="server" ID="myPlaceholder"></asp:PlaceHolder>
<td runat="server" ID="myCell2"></td>
</tr>
...
This generates the following error:
System.Web.UI.HtmlControls.HtmlTableCellCollection must have items of type 'System.Web.UI.HtmlControls.HtmlTableCell'. 'asp:PlaceHolder' is of type 'System.Web.UI.WebControls.PlaceHolder'.
The reason for the PlaceHolder
is I would like to dynamically generate that cell (for example choosing between TD
and TH
, or choosing whether to create it at all.
Is there an easy way to do this? Or maybe I should just create my own custom control which inherits HtmlTableCell
?
I have noticed that viewstate for certain table elements are keyed by the ordinal (index into child control collection), which means I also sometimes cannot dynamically generate cells when I would expect to be able to. Is there some general best practice with regards to this?
I have also considered always creating the TD, but just hiding it. The problem is that I use rowspan
on a previous row, meaning different rows will render different numbers of cells. This is conditional and can change between postbacks (by enabling / disabling a row).
Upvotes: 2
Views: 5010
Reputation: 4569
The solution I use when I run into this is to replace the <tr>
with an <asp:literal>
and write the HTML for the table row myself.
Example:
<asp:literal runat="server" ID="trRow" Mode="PassThrough" />
<td runat="server" ID="myCell1"></td>
<asp:PlaceHolder runat="server" ID="myPlaceholder"></asp:PlaceHolder>
<td runat="server" ID="myCell2"></td>
</tr>
Then in the code behind
Literal trRow = (Literal)e.Item.FindControl("trRow");
// ... some code here decides on CSS class I want to use
trRow.Text = string.Format("<tr class=\"{0}\">", strCssClass);
Upvotes: 0
Reputation: 36896
I managed to solve it by making a simple custom control:
public class HtmlTableCellPH : HtmlTableCell
{
public HtmlTableCellPH()
{
}
public HtmlTableCellPH(string tagName)
: base(tagName)
{
}
public override void RenderControl(HtmlTextWriter writer)
{
this.RenderChildren(writer);
}
}
And now the ascx is:
...
<tr runat="server" ID="mytr">
<td runat="server" ID="myCell1"></td>
<ns:HtmlTableCellPH runat="server" ID="myPlaceholder"></ns:HtmlTableCellPH>
<td runat="server" ID="myCell2"></td>
</tr>
...
Upvotes: 0
Reputation: 2392
There are a couple of ways you could get around this.
1. Remove the runat="server"
attributes from the table
and tr
tags. The down side to this method is that you won't be able to modify those tags from the server-side. You will still be able to modify any td
tags though.
2. Generate the entire table dynamically from server-side code.
HTML
<table runat="server" id="Table1">
</table>
C# Server-side code
HtmlTableRow row = new HtmlTableRow();
HtmlTableCell cell = new HtmlTableCell();
cell.InnerText = "Text goes here.";
row.Cells.Add(cell);
this.Table1.Rows.Add(row);
Upvotes: 1
Reputation: 16144
You can use ASP.net Table Webcontrol for creating your table dynamically (if you consider of generating whole table from your code.)
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.table.aspx
Upvotes: 1