views:

2724

answers:

3

Hey Guys,

Getting the following error

Multiple controls with the same ID 'ltlItemCode' were found. FindControl requires that controls have unique IDs.

This Error does not happen on page loads but when I change the value of a drop down which has AutoPostBack="true".

Code is

`//Number of Services numberofServices = Int32.Parse(DCCFunctions.GetNumServicesPerRoom(roomId.ToString())); additionalServices = new UserControls_AdditionalService[numberofServices - 1];

    String htmlTable = String.Empty;
    Int32 cell = 1;
    Int32 rows = numberofServices;
    Int32 cols = 4;


    TableHeaderRow h = new TableHeaderRow();
    TableHeaderCell hc1 = new TableHeaderCell();
    hc1.Text = "Item Description";
    h.Cells.Add(hc1);
    TableHeaderCell hc2 = new TableHeaderCell();
    hc2.Text = "Item Price";
    h.Cells.Add(hc2);
    TableHeaderCell hc3 = new TableHeaderCell();
    hc3.Text = "Item Quantity";
    h.Cells.Add(hc3);
    TableHeaderCell hc4 = new TableHeaderCell();
    hc4.Text = "Item Sub Total";
    h.Cells.Add(hc4);
    Table1.Rows.Add(h);

    // Open database connection
    DBConnection conn = new DBConnection();

    // Retrieve details
    SqlCommand sqlGetDetails = conn.SetStoredProcedure("spGetAdditionalServicesDetails");
    DBConnection.AddNewParameter(sqlGetDetails, "@roomId", ParameterDirection.Input, SqlDbType.Int, roomId);

    try
    {
        conn.Open();

        SqlDataReader reader_list = sqlGetDetails.ExecuteReader();
        if (reader_list.HasRows)
        {
            while (reader_list.Read())
            {
                //returnVal = reader_list["Num"].ToString();
                htmlTable += "<tr>" + Environment.NewLine;
                TableRow r = new TableRow();

                additionalServices[cell - 1] = (ASP.usercontrols_additionalservice_ascx)LoadControl("~/UserControls/AdditionalService.ascx");

                Literal ItemCode = (Literal)additionalServices[cell - 1].FindControl("ltlItemCode") as Literal;
                ItemCode.Text = reader_list["itemDescription"].ToString();


                Literal ItemPrice = (Literal)additionalServices[cell - 1].FindControl("ltlItemPrice") as Literal;
                ItemPrice.Text = "€" + reader_list["unitPrice"].ToString();

                Literal ItemTotal = (Literal)additionalServices[cell - 1].FindControl("ltlTotalPrice") as Literal;
                ItemTotal.Text = "€" + "0";

                TableCell ItemCodeCell = new TableCell();
                ItemCodeCell.Controls.Add((Literal)additionalServices[cell - 1].FindControl("ltlItemCode") as Literal);

                TableCell ItemCodePriceCell = new TableCell();
                ItemCodePriceCell.Controls.Add((Literal)additionalServices[cell - 1].FindControl("ltlItemPrice") as Literal);

                TableCell ItemCodeTotalCell = new TableCell();
                ItemCodeTotalCell.Controls.Add((Literal)additionalServices[cell - 1].FindControl("ltlTotalPrice") as Literal);

                TableCell c = new TableCell();
                DropDownList qtyList = (DropDownList)additionalServices[cell - 1].FindControl("qtyList") as DropDownList;
                qtyList.Items.Add(new System.Web.UI.WebControls.ListItem("Select Quantity...", "0"));
                qtyList.DataBind();

                for (Int32 count = 1; count < 101; count++)
                {
                    qtyList.Items.Add(new System.Web.UI.WebControls.ListItem(count.ToString(),count.ToString()));
                }
                //c.ColumnSpan = 5;
                c.Controls.Add((DropDownList)additionalServices[cell - 1].FindControl("qtyList") as DropDownList);


                r.Cells.Add(ItemCodeCell);
                r.Cells.Add(ItemCodePriceCell);
                r.Cells.Add(c);
                r.Cells.Add(ItemCodeTotalCell);
                //r.Controls.Add(additionalServices[cell - 1]);
                //cell += 1;

                // Add the row
                Table1.Rows.Add(r);
            }
        }
        reader_list.Close();
    }
    catch (Exception ex)
    {
        M1Utils.ErrorHandler(ex);
    }
    finally
    {
        conn.Close();
    }`
+1  A: 

ItemCodeCell.Controls.Add((Literal)additionalServices[cell - 1].FindControl("ltlItemCode") as Literal);

I'm guessing that is the problem, it looks like you're adding the same control over and over, but I'm not sure. Try changing the .ID of that newly added Literal.

Also, I've never used "EnsureID()" before but it seems that it may help. Something along the lines of


Literal duplicateLiteral = (Literal)additionalServices[cell - 1].FindControl("ltlItemCode") as Literal;
duplicateLiteral.EnsureID();
ItemCodeCell.Controls.Add(duplicateLiteral);

That may not work though, since it looks like it would insert the same copy of duplicateLiteral over and over, although, I'm not sure.

Allen
What is the syntax for using Ensue ID ?
I edited the answer to include a snippet using EnsureID(). Let me know if that works
Allen
+1  A: 

I don't think EnsureID will solve your problem, as that will only create an ID for controls which do not already have one.

As Allen points out, you are adding the same control over and over again. You need to create new controls, which will give you new IDs. You are also calling FindControl for a control you already have a reference to... ? Copy data from the existing control if you need to, but do not add the existing control repeatedly. For a literal, probably the only thing of value in it is the text? So change your code to something like:

Literal ItemCode = (Literal)additionalServices[cell - 1].FindControl("ltlItemCode") as Literal;
ItemCode.Text = reader_list["itemDescription"].ToString();

Literal ItemCode2 = new Literal();  //create a new control
ItemCode2.Text = ItemCode.Text;     //copy the data you need

TableCell ItemCodeCell = new TableCell();
ItemCodeCell.Controls.Add(ItemCode2);  // add new control
Bryan
+2  A: 

I agree that it looks like you are adding the same Control over and over which causes a naming conflict. It also looks like you may be adding controls to other controls' Controls collections in the wrong order. For example, you are adding in this order:

TableHeaderRow h = new TableHeaderRow();    
TableHeaderCell hc1 = new TableHeaderCell();    
hc1.Text = "Item Description";    
h.Cells.Add(hc1);    
TableHeaderCell hc2 = new TableHeaderCell();    
hc2.Text = "Item Price";    
h.Cells.Add(hc2);    
TableHeaderCell hc3 = new TableHeaderCell();    
hc3.Text = "Item Quantity";    
h.Cells.Add(hc3);    
TableHeaderCell hc4 = new TableHeaderCell();    
hc4.Text = "Item Sub Total";    
h.Cells.Add(hc4);    
Table1.Rows.Add(h);

When you should really be adding in this order:

TableHeaderRow h = new TableHeaderRow();   
Table1.Rows.Add(h); 
TableHeaderCell hc1 = new TableHeaderCell();
h.Cells.Add(hc1);   
hc1.Text = "Item Description";      
TableHeaderCell hc2 = new TableHeaderCell();
h.Cells.Add(hc2);    
hc2.Text = "Item Price";       
TableHeaderCell hc3 = new TableHeaderCell();
h.Cells.Add(hc3);    
hc3.Text = "Item Quantity";      
TableHeaderCell hc4 = new TableHeaderCell();
h.Cells.Add(hc4);    
hc4.Text = "Item Sub Total";

As a rule, I always try to add a new control to the parent Controls collection as soon as possible to ensure that any child controls inherit the correct UniqueID. If you create a new Control X and start adding to X.Controls BEFORE adding X to the parent Controls collection then the child controls may not inherit the right UniqueID.

jakejgordon