Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Noob alert - Programatically build table on page load

Status
Not open for further replies.

cawthor

Programmer
May 31, 2001
89
US
I'm trying to add rows to a table on page load instead of building the whole table in the designer. However, the following code produces no results. No error, just nothing on the screen. I'm defining the table in the html as follows:

<asp:Table id="Table1" BorderWidth="1" GridLines="Both" runat="server" />

then in the codebehind:

Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
Dim rows, cells, j, i
rows = 3
cells = 2
For j = 0 To rows - 1
Dim r As New TableRow()
For i = 0 To cells - 1
Dim c As New TableCell()
c.Controls.Add(New LiteralControl("row " & j & ", cell " & i))
r.Cells.Add(c)
Next
Table1.Rows.Add(r)
Next
End Sub

I'm a complete noob to .NET. Any help would be appreciated.
 
say I have a table with 50 rows, each with an input box. In ASP I'd do something like:

<table>
<%
for i = 1 to 50
%>
<tr>
<td>
<input type="text" name="myTextBox_<%=i%>">
</td>
</tr>
<%
next
%>
</table>

I wouldn't have to build the entire table up-front. I was trying to figure out how I'd achieve something like this in .NET.
 
Why do you want to put a TextBox in a table? What is the table actually for?Are you trying to layout your page? Are the textboxes going to be used to gather data?

If you explain why you need to do this, you will get better help than us having to guess what the best solution might be.


-------------------------------------------------------

Mark,
[URL unfurl="true"]http://aspnetlibrary.com[/url]
[URL unfurl="true"]http://mdssolutions.co.uk[/url] - Delivering professional ASP.NET solutions
[URL unfurl="true"]http://weblogs.asp.net/marksmith[/url]
 
I would place a Literal control into the page.

Then in you PageLoad:
Code:
Dim sHtml as String = "<table>"
For i = 1 To 50
    sHTML += "<tr><td>"
    sHTML += "<input type=""text"" name=""myTextBox_" & i.ToString & """>"
    sHTML += "</td></tr>"
Next
sHTML += "</table>"
Literal1.Text = sHTML

Senior Software Developer
 
Each row of the table would contain 5 text boxes (which make up a single line item). I am using these text boxes to gather various data elements from the user. The user can submit more than 1 line item at a time, so I want multiple lines (50 was an exageration). Say 6 rows. Instead of creating 30 text boxes in the html section, I wanted to use a table to arrange these text boxes, and dynamically create 6 rows. The above example is how I would have done this in the past in ASP. Define 1 row and loop 6 times (appending the row count to the text box name to create a unique instance).

I think this is more detail than is required, this is just an example scenario that can be applied to my original question, how can you dynamically add rows to a table object. It doesn't matter that it's a text box in the table cell, it could be anything.
 
SiriusBlackOp,

Using that method, the user will find it hard to interact with the actual row if he needs to add any conditional formatting. Plus, in the example you gave above there would now be around 150 string objects in memory. If you were to go down that route you should use the StringBuilder object.

cawthor,

I still don't think dynamically building a table is necessarily the best approach for what you need, but as you simply want a working example try this:
Code:
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim rows As Integer = 3
        Dim cells As Integer = 2
        Dim r As TableRow
        Dim c As TableCell

        For i As Integer = 1 To rows
            r = New TableRow
            For j As Integer = 1 To cells
                c = New TableCell
                c.Controls.Add(New TextBox())
                r.Cells.Add(c)
            Next
            Table1.Rows.Add(r)
        Next

    End Sub


-------------------------------------------------------

Mark,
[URL unfurl="true"]http://aspnetlibrary.com[/url]
[URL unfurl="true"]http://mdssolutions.co.uk[/url] - Delivering professional ASP.NET solutions
[URL unfurl="true"]http://weblogs.asp.net/marksmith[/url]
 
There is ONE string object that is being apended 151 times, and nothing was stated about conditional formating. A simple question got a simple answer.

I like your last example though. Nice. He could also use a DataBound option via a DataSet and a DataGrid with a Template column.

Senior Software Developer
 
There is ONE string object that is being apended 151 times, and nothing was stated about conditional formating. A simple question got a simple answer.
That doesn't matter. If you append data to a string the internal framework methods of .NET create an object for each string so you actually end up with 150 in memory. The StringBuilder object eliviates this problem. I understand the poster asked a relatively simple question though (hence your response), I just felt there was a better method which would allow further scope if needed.

Yes, I'd probably use a GridView as well and do a batch insert depending on the actual volumne of data.


-------------------------------------------------------

Mark,
[URL unfurl="true"]http://aspnetlibrary.com[/url]
[URL unfurl="true"]http://mdssolutions.co.uk[/url] - Delivering professional ASP.NET solutions
[URL unfurl="true"]http://weblogs.asp.net/marksmith[/url]
 
That doesn't matter. If you append data to a string the internal framework methods of .NET create an object for each string so you actually end up with 150 in memory. The StringBuilder object eliviates this problem.

That is Not correct. Every time a string is appended in the .NET Framework the original object is destroyed and a new one is created. This does result in some additional memory allocation overhead that the use of a String Builder would alleviate because it uses its own internal string buffer, BUT there is still only ONE object left in memory after 151 concatenations of an original string.

Senior Software Developer
 
Every time a string is appended in the .NET Framework the original object is destroyed and a new one is created.
True, but it's the copy part of that sentence that is the key. Every single time you append a value to the string an exact copy of that string is inserted into memory, and then the original is deleted. So, you actually ended up with 150 extra objects being added to the memory when you could have easily avoided this with the StringBuilder class. It's often said that anytime you need to append more than 5-10 times to a string that you should use the StringBuilder class instead.

Also, whilst in this case it may be relatively small, there's also the option of the time it takes to create these objects to consider. Take this simple example and see how it takes longer for the String version vs the StringBuilder one:
Code:
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        ' String test
        Dim start1 As DateTime = System.DateTime.Now
        Dim sHtml As String = "<table>"

        For i As Integer = 1 To 150
            sHtml += "<tr><td>"
            sHtml += "<input type=""text"" name=""TextBox1_" & i.ToString & """>"
            sHtml += "</td></tr>"
        Next
        sHtml += "</table>"
        Dim end1 As DateTime = System.DateTime.Now

        ' StringBuilder test
        Dim start2 As DateTime = System.DateTime.Now
        Dim sHtml2 As New StringBuilder("<table>")

        For j As Integer = 1 To 150
            sHtml2.Append("<tr><td>")
            sHtml2.Append("<input type=""text"" name=""TextBox2_" & j.ToString & """>")
            sHtml2.Append("</td></tr>")
        Next
        sHtml += "</table>"
        Dim end2 As DateTime = System.DateTime.Now

        ' Results
        Response.Write("String test took " & CType(end1 - start1, TimeSpan).TotalMilliseconds & " milliseconds")
        Response.Write("StringBuilder test took " & CType(end2 - start2, TimeSpan).TotalMilliseconds & " milliseconds")

    End Sub
In high volume sites like I deal with, the performance and memory issues are something which have to be monitored and any savings no matter how small can have a dramatic effect on the site as a whole.

BUT there is still only ONE object left in memory after 151 concatenations of an original string.
Yes, there is only one left at the end, my point is that you created 150 extra along the way.



-------------------------------------------------------

Mark,
[URL unfurl="true"]http://aspnetlibrary.com[/url]
[URL unfurl="true"]http://mdssolutions.co.uk[/url] - Delivering professional ASP.NET solutions
[URL unfurl="true"]http://weblogs.asp.net/marksmith[/url]
 
I agree that the string builder is better. I was just trying to give cawthor a simple answer so that he understood that he could fill a Literal Control with HTML.


Senior Software Developer
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top