In this article I will provide solution to the error (exception): - Multiple controls with the same ID were found. FindControl requires that controls have unique IDs.
The above error occurs while creating dynamic controls in ASP.Net using C# and VB.Net.
The Error
Multiple controls with the same ID were found. FindControl requires that controls have unique IDs.
The Cause
The error “Multiple controls with the same ID were found. FindControl requires that controls have unique IDs.” occurs when dynamic controls are created without unique IDs, thus ASP.Net raises the above exception to notify the developer that he has to provide Unique IDs to each dynamically created control.
The Solution
The following example illustrates correct usage of dynamic controls and how to give Unique IDs to each dynamically created control.
HTML Markup
The HTML Markup consists of an ASP.Net Panel control and two Buttons, one for adding TextBoxes and other one for getting the values of the dynamically generated TextBoxes.
<asp:Panel ID="pnlTextBoxes" runat="server">
</asp:Panel>
<hr />
<asp:Button ID="btnAdd" runat="server" Text="Add New" OnClick="AddTextBox" />
<asp:Button ID="btnGet" runat="server" Text="Get Values" OnClick="GetTextBoxValues" />
Dynamically creating and adding TextBoxes on Button Click
When the Add Button is clicked, first the count of all the TextBoxes present in the Panel control is determined and then it is incremented to generate an Index which will be used for generating a unique ID for the TextBox control.
The unique ID is passed to the CreateTextBox method, which creates a dynamic TextBox and appends it to the Panel control.
Note: It is very important to give a common prefix (example txtDynamic) for all TextBoxes as it will be used to find and recreate all dynamic TextBoxes on PostBack.
C#
protected void AddTextBox(object sender, EventArgs e)
{
int index = pnlTextBoxes.Controls.OfType<TextBox>().ToList().Count + 1;
this.CreateTextBox("txtDynamic" + index);
}
private void CreateTextBox(string id)
{
TextBox txt = new TextBox();
txt.ID = id;
pnlTextBoxes.Controls.Add(txt);
Literal lt = new Literal();
lt.Text = "<br />";
pnlTextBoxes.Controls.Add(lt);
}
VB.Net
Protected Sub AddTextBox(sender As Object, e As EventArgs)
Dim index As Integer = pnlTextBoxes.Controls.OfType(Of TextBox)().ToList().Count + 1
Me.CreateTextBox("txtDynamic" & index)
End Sub
Private Sub CreateTextBox(id As String)
Dim txt As New TextBox()
txt.ID = id
pnlTextBoxes.Controls.Add(txt)
Dim lt As New Literal()
lt.Text = "<br />"
pnlTextBoxes.Controls.Add(lt)
End Sub
Retaining the dynamic TextBoxes on PostBack
In order to retain the dynamic TextBoxes across PostBacks, we need to make use of Page’s PreInit event to recreate the dynamic TextBoxes using the Request.Form collection.
First all the keys containing the string txtDynamic are fetched and then for each key the CreateTextBox method is called.
C#
protected void Page_PreInit(object sender, EventArgs e)
{
List<string> keys = Request.Form.AllKeys.Where(key => key.Contains("txtDynamic")).ToList();
int i = 1;
foreach (string key in keys)
{
this.CreateTextBox("txtDynamic" + i);
i++;
}
}
VB.Net
Protected Sub Page_PreInit(sender As Object, e As EventArgs) Handles Me.PreInit
Dim keys As List(Of String) = Request.Form.AllKeys.Where(Function(key) key.Contains("txtDynamic")).ToList()
Dim i As Integer = 1
For Each key As String In keys
Me.CreateTextBox("txtDynamic" & i)
i += 1
Next
End Sub
Getting values of dynamically created TextBoxes
When the Get Button is clicked, a loop is executed over all the TextBoxes present inside the Panel control. Inside the loop, the ID and the Value of each TextBox is fetched and displayed using JavaScript Alert message box.
C#
protected void GetTextBoxValues(object sender, EventArgs e)
{
string message = "";
foreach (TextBox textBox in pnlTextBoxes.Controls.OfType<TextBox>())
{
message += textBox.ID + ": " + textBox.Text + "\\n";
}
ClientScript.RegisterClientScriptBlock(this.GetType(), "alert", "alert('" + message + "');", true);
}
VB.Net
Protected Sub GetTextBoxValues(sender As Object, e As EventArgs)
Dim message As String = ""
For Each textBox As TextBox In pnlTextBoxes.Controls.OfType(Of TextBox)()
message += textBox.ID + ": " + textBox.Text + "\n"
Next
ClientScript.RegisterClientScriptBlock(Me.GetType(), "alert", "alert('" & message & "');", True)
End Sub
Screenshot
Demo
Downloads