Help with PlaceHolders and Aligning Controls

Hello all -
This is for the Web using C#

Yesterday i posted about creating controls dynamically and building tables. I decided to go a different direction.

I'm now using PlaceHolders.  I'm creating 7 controls on a click of a button and everytime the user clicks the Add button another 7 controls are created. it consists of 3 labels. 3 textboxes and 1 button.

How it works right now, all the controls are created in one PlaceHolder and it looks fine when they hit the Add button once. But when the button is hit for the second time it shows 12 controls on one row and 2 controls on another row.

I would like it to show 7 controls per row, this way it is all aligned.
If that isn't possible, is there a way to add the controls to a new PlaceHolder everytime the Add button is clicked.  
Also, when i click the Add button and fill out the three fields, then click the Add button again, the first field is blank but the other two fields still have the text i entered.

Thanks a lot in advance. My code is below.

protected void Page_Load(object sender, EventArgs e)
    {
               CreateControls();        
    }

protected void btnAdd_Click(object sender, EventArgs e)
{
        int count = 0;
        if (ViewState["count"] != null)
        {
            count = (int)ViewState["count"];
        }
        count++;
               
        ViewState["count"] = count;
        CreateControls();
}

private void CreateControls()
    {

        int count = 0;
        if (ViewState["count"] != null)
        {
            count = (int)ViewState["count"];
        }

        while (PlaceHolder1.Controls.Count < count * 7)
        {
            // -----INVOICE-----
           //Control One
            Label lblInvoice = new Label();
            PlaceHolder1.Controls.Add(lblInvoice);
            lblInvoice.ID = "lblInvoice" + PlaceHolder1.Controls.Count.ToString();
            lblInvoice.Text = "Invoice #:";

            //Control Two
            TextBox txtInvoice = new TextBox();
            PlaceHolder1.Controls.Add(txtInvoice);
            txtInvoice.ID = "txtInvoice:" + PlaceHolder1.Controls.Count.ToString();
            txtInvoice.Text = "";
            txtInvoice.Height = 18;

            // -----AMOUNT-----
            //Control Three
            Label lblAmount = new Label();
            PlaceHolder1.Controls.Add(lblAmount);
            lblAmount.ID = "lblAmount" + PlaceHolder1.Controls.Count.ToString();
            lblAmount.Text = "Amount:";

            //Control Four
            TextBox txtAmount = new TextBox();
            PlaceHolder1.Controls.Add(txtAmount);
            txtAmount.ID = "txtAmount" + PlaceHolder1.Controls.Count.ToString();
            txtAmount.Text = "";
            txtAmount.Height = 18;

            // -----DATE-----
            //Control Five
            Label lblDateRecieved = new Label();
            PlaceHolder1.Controls.Add(lblDateRecieved);
            lblDateRecieved.ID = "lblDateRecieved" + PlaceHolder1.Controls.Count.ToString();
            lblDateRecieved.Text = "Date:";

            //Control SIx
            TextBox txtDateRecieved = new TextBox();
            PlaceHolder1.Controls.Add(txtDateRecieved);
            txtDateRecieved.ID = "txtDateRecieved" + PlaceHolder1.Controls.Count.ToString();
            txtDateRecieved.Text = "";
            txtDateRecieved.Height = 18;

            //Control Seven
            Button btnCalendar = new Button();
            PlaceHolder1.Controls.Add(btnCalendar);
            btnCalendar.ID = "btnCalendar" + PlaceHolder1.Controls.Count.ToString();
            btnCalendar.BackColor = System.Drawing.Color.White;
            btnCalendar.CssClass = "calendarImage";
            btnCalendar.Width = 27;
        }
       
    }

JordanBlacklerAsked:
Who is Participating?
 
strickddConnect With a Mentor Commented:
i guess i wasn't clear enough in my comment "//Loop starts here to print controls"

What i meant is you put your code for the For Loop, While Loop, or whatever you are doing to loop and create controls:

for(int i=0; i<numControlsToCreate; i++)
{
      tableInfo = new Literal();
tableInfo.Text = "<tr><td>";

PlaceHolderControl.Controls.Add(tableInfo);
PlaceHolderControl.Controls.Add(MyFirstTextBox);

tableInfo = new Literal();
tableInfo.Text = "</td><td>";
}

NOTE: you will have to "new" all the controls you are adding and give distinct IDs to them each loop. If you do not then you will have problems referencing controls. You also want to come up with a naming convention for the controls to reference them easily. For exmple,

textBoxControl.ID = "firstTextBox" + i;

To reference it:
PlaceHolderControl.FindControl("firstTextBox" + i);
0
 
strickddCommented:
if you add literals to the placeholder containing table rows, you can align is just fine:

Literal tableInfo = new Literal();
tableInfo.Text = "<table>";

PlaceHolderControl.Controls.Add(tableInfo);

//Loop starts here to print controls
tableInfo = new Literal();
tableInfo.Text = "<tr><td>";

PlaceHolderControl.Controls.Add(tableInfo);
PlaceHolderControl.Controls.Add(MyFirstTextBox);

tableInfo = new Literal();
tableInfo.Text = "</td><td>";

//repeat as above and end loop.
0
 
JordanBlacklerAuthor Commented:
Thanks for the response.
Do you think you can plug it into my code above.
When i tried i got this error:

"Failed to load viewstate.  The control tree into which viewstate is being loaded must match the control tree that was used to save viewstate during the previous request.  For example, when adding controls dynamically, the controls added during a post-back must match the type and position of the controls added during the initial request"
0
Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

 
strickddCommented:
why don't you post the code that you have with my code in it and i'll tell you what to change. That way I can see all your variables and field declarations in the proper context.
0
 
JordanBlacklerAuthor Commented:
Am i supposed to add this section for every control i'm creating? I'm a little bit lost i think.

//Loop starts here to print controls
tableInfo = new Literal();
tableInfo.Text = "<tr><td>";

PlaceHolderControl.Controls.Add(tableInfo);
PlaceHolderControl.Controls.Add(MyFirstTextBox);

tableInfo = new Literal();
tableInfo.Text = "</td><td>";
0
 
JordanBlacklerAuthor Commented:
I get an error when i click the Add button the second time.
"Failed to load viewstate.  The control tree into which viewstate is being loaded must match the control tree that was used to save viewstate during the previous request.  For example, when adding controls dynamically, the controls added during a post-back must match the type and position of the controls added during the initial request"

protected void Page_Load(object sender, EventArgs e)
    {
               CreateControls();        
    }

protected void btnAdd_Click(object sender, EventArgs e)
{
        int count = 0;
        if (ViewState["count"] != null)
        {
            count = (int)ViewState["count"];
        }
        count++;
               
        ViewState["count"] = count;
        CreateControls();
}

private void CreateControls()
    {

        int count = 0;
        if (ViewState["count"] != null)
        {
            count = (int)ViewState["count"];
        }
       
        Literal tableInfo = new Literal(); //////// your code
        tableInfo.Text = "<table>";   ////////// your code

        PlaceHolder1.Controls.Add(tableInfo);

        while (PlaceHolder1.Controls.Count < count * 7)
           
        {
            tableInfo = new Literal();////////// your code
            tableInfo.Text = "<tr><td>";////////// your code

            PlaceHolder1.Controls.Add(tableInfo);
             // -----INVOICE-----
            Label lblInvoice = new Label();
            PlaceHolder1.Controls.Add(lblInvoice);
            lblInvoice.ID = "lblInvoice" + PlaceHolder1.Controls.Count.ToString();
            lblInvoice.Text = "Invoice #:";

            TextBox txtInvoice = new TextBox();
            PlaceHolder1.Controls.Add(txtInvoice);
            txtInvoice.ID = "txtInvoice:" + PlaceHolder1.Controls.Count.ToString();
            txtInvoice.Text = "";
            txtInvoice.Height = 18;
            txtInvoice.Width = 100;
            // -----AMOUNT-----
            Label lblAmount = new Label();
            PlaceHolder1.Controls.Add(lblAmount);
            lblAmount.ID = "lblAmount" + PlaceHolder1.Controls.Count.ToString();
            lblAmount.Text = "Amount:";

            TextBox txtAmount = new TextBox();
            PlaceHolder1.Controls.Add(txtAmount);
            txtAmount.ID = "txtAmount" + PlaceHolder1.Controls.Count.ToString();
            txtAmount.Text = "";
            txtAmount.Height = 18;
            txtAmount.Width = 100;
            // -----DATE-----
            Label lblDateRecieved = new Label();
            PlaceHolder1.Controls.Add(lblDateRecieved);
            lblDateRecieved.ID = "lblDateRecieved" + PlaceHolder1.Controls.Count.ToString();
            lblDateRecieved.Text = "Date:";

            TextBox txtDateRecieved = new TextBox();
            PlaceHolder1.Controls.Add(txtDateRecieved);
            txtDateRecieved.ID = "txtDateRecieved" + PlaceHolder1.Controls.Count.ToString();
            txtDateRecieved.Text = "";
            txtDateRecieved.Height = 18;
            txtDateRecieved.Width = 100;

            Button btnCalendar = new Button();
            PlaceHolder1.Controls.Add(btnCalendar);
            btnCalendar.ID = "btnCalendar" + PlaceHolder1.Controls.Count.ToString();
            btnCalendar.BackColor = System.Drawing.Color.White;
            btnCalendar.CssClass = "calendarImage";
            btnCalendar.Width = 27;
           
            tableInfo = new Literal();////////// your code
            tableInfo.Text = "</td></tr>";////////// your code
     }
}
0
 
JordanBlacklerAuthor Commented:
I added the below section of the code inside the loop rather then outside the loop and it works now.
           Literal tableInfo = new Literal();
            tableInfo.Text = "<table>";
            PlaceHolder1.Controls.Add(tableInfo);

The only problem now is that the first textbox of each row doesn't hold the text when i click the Add button. The two other textboxes keep the data.
Any ideas?

Thanks for your help.

0
 
JordanBlacklerAuthor Commented:
Nevermind, i got it to work. I had to add the last section of the code to the placeholder
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.