I am trying to dynamically add some control in an asp.net page. It gets rendered fin, after clicking a button which causes postback I get the following error
[HttpException (0x80004005): Multiple controls with the same
ID 'ParentTextBox_ChildTextBox_TV_PostRender' were found. FindControl requires that controls have unique IDs.]
System.Web.UI.Control.FillNamedControlsTable(Control namingContainer, ControlCollection controls) +273
System.Web.UI.Control.EnsureNamedControlsTable() +61
System.Web.UI.Control.FindControl(String id, Int32 pathOffset) +222
System.Web.UI.Control.FindControl(String id, Int32 pathOffset) +327
System.Web.UI.Page.FindControl(String id) +38
System.Web.UI.Page.ProcessPostData(NameValueCollection postData, Boolean fBeforeLoad) +232
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1434
I have tried several different things, none of which work. I thought removing the control OnInit or on page_load like this
Control c = Page.FindControl("ParentTextBox_ChildTextBox_TV_PostRender");
Page.Controls.Remove(c);
will work but it doesn't
Code of custom tree view control
// file ContainerTreeView.cs
using System.Web.UI;
using System.Web.UI.WebControls;
using System;
namespace DASHBOARD
{
[ToolboxData("<{0}:ContainerTreeView runat=server></{0}:ContainerTreeView>")]
public class ContainerTreeView : TreeView, INamingContainer
{
public ContainerTreeView()
: base()
{
PathSeparator = ClientIDSeparator;
}
protected override void OnInit(EventArgs e)
{
// Initialize Child Controls
RecurseUpdateNodes(Nodes);
base.OnInit(e);
}
protected const String s_strNodeValueSeparator = "_TV_";
protected virtual void RecurseUpdateNodes(TreeNodeCollection parrNodes)
{
if (parrNodes == null || parrNodes.Count == 0)
return;
foreach (TreeNode pNode in parrNodes)
{
ContainerTreeNode pContainerNode = pNode as ContainerTreeNode;
if (pContainerNode != null)
{
// update node pre / post rendering control IDs id
if (pContainerNode.PreRenderContainer != null)
{
pContainerNode.PreRenderContainer.ID = pContainerNode.PreRenderContainer.ID.Insert(0, pNode.ValuePath + s_strNodeValueSeparator);
Controls.Add(pContainerNode.PreRenderContainer);
}
if (pContainerNode.PostRenderContainer != null)
{
pContainerNode.PostRenderContainer.ID = pContainerNode.PostRenderContainer.ID.Insert(0, pNode.ValuePath + s_strNodeValueSeparator);
Controls.Add(pContainerNode.PostRenderContainer);
}
}
// update children
RecurseUpdateNodes(pNode.ChildNodes);
}
}
public ContainerTreeNode CreateTreeNode()
{
return new ContainerTreeNode(this, false);
}
protected override TreeNode CreateNode()
{
return CreateTreeNode();
}
// collection of child controls
protected override ControlCollection CreateControlCollection()
{
return new ControlCollection(this);
}
protected override void RenderChildren(HtmlTextWriter writer)
{
// do not render children as they will be rendered within treeview nodes
// base.RenderChildren(writer);
}
}
}
page where I am adding the tree
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Xml.Linq;
namespace DASHBOARD
{
public partial class testTreeEdit : System.Web.UI.Page
{
ContainerTreeView m_pTreeView = null;
protected override void OnInit(EventArgs e)
{
Control c = Page.FindControl("ParentTextBox_ChildTextBox_TV_PostRender");
Page.Controls.Remove(c);
tb.Text += "Removed Control";
base.OnInit(e);
}
#region main
protected void Page_Load(object sender, EventArgs e)
{
if (CheckBox1.Checked)
{
renderEditTree();
}
else
{
makeTree();
TreeView1.ExpandAll();
}
}
#endregion
#region editableTreeView
/** //function to render editable tree view
protected void renderEditTree()
{
m_pTreeView = new ContainerTreeView();
ContainerTreeNode pNodeParent = m_pTreeView.CreateTreeNode();
pNodeParent.Value = "Parent";
pNodeParent.Text = "Parent";
pNodeParent.Expanded = true;
m_pTreeView.Nodes.Add(pNodeParent);
/**ContainerTreeNode pNodeChildDropDown = m_pTreeView.CreateTreeNode();
pNodeChildDropDown.Value = "ChildDropDown";
pNodeChildDropDown.Text = String.Empty;
DropDownList pList = new DropDownList();
pList.ID = "ID_DropDown";
pList.Items.Add("AAA");
pList.Items.Add("BBB");
pList.Items.Add("CCC");
pNodeChildDropDown.PostRenderControls.Add(pList);
pNodeParent.ChildNodes.Add(pNodeChildDropDown);
/**ContainerTreeNode pNodeChildButton = m_pTreeView.CreateTreeNode();
pNodeChildButton.Value = "ChildButton";
pNodeChildButton.Text = String.Empty;
Button pButton = new Button();
pButton.ID = "ID_Button";
pButton.Text = "PostBack";
pNodeChildButton.PostRenderControls.Add(pButton);
pNodeParent.ChildNodes.Add(pNodeChildButton);
/** ContainerTreeNode pNodeChildTextBox = m_pTreeView.CreateTreeNode();
pNodeChildTextBox.Value = "ChildTextBox";
pNodeChildTextBox.Text = String.Empty;
TextBox pTextBox = new TextBox();
pTextBox.ID = "ID_TextBox";
pTextBox.Text = "Some text";
pNodeChildTextBox.PostRenderControls.Add(pTextBox);
pNodeParent.ChildNodes.Add(pNodeChildTextBox);
this.treeViewContainer.Controls.Add(m_pTreeView);
}*/
//load XML file and use it to make the tree view
public void renderEditTree()
{
m_pTreeView = new ContainerTreeView();
XDocument document = XDocument.Load(Server.MapPath("~/Releases_files/releases.xml"));
foreach (XElement element in document.Descendants("Release"))
{
XName name0 = "version";
XAttribute a0 = element.Attribute(name0);
string temp0 = a0.Value;
ContainerTreeNode pmTextBox = m_pTreeView.CreateTreeNode();
pmTextBox.Value = "ParentTextBox";
pmTextBox.Text = String.Empty;
TextBox pTextBox = new TextBox();
pTextBox.ID = temp0;
pTextBox.Text = temp0;
pmTextBox.PostRenderControls.Add(pTextBox);
m_pTreeView.Nodes.Add(pmTextBox);
//n0.Text = temp0;
//TreeView1.Nodes.Add(n0);
foreach (XElement myElement in element.Descendants("Feature"))
{
XName name = "Name";
XAttribute a = myElement.Attribute(name);
string temp = a.Value;
ContainerTreeNode pcTextBox = m_pTreeView.CreateTreeNode();
pcTextBox.Value = "ChildTextBox";
pcTextBox.Text = String.Empty;
TextBox p2TextBox = new TextBox();
p2TextBox.ID = temp;
p2TextBox.Text = temp;
pcTextBox.PostRenderControls.Add(p2TextBox);
pmTextBox.ChildNodes.Add(pcTextBox);
}
this.treeViewContainer.Controls.Add(m_pTreeView);
}
}
#endregion
#region simpleTreeView
//old code
//load XML file and use it to make the tree view
public void makeTree()
{
TreeView1.Nodes.Clear();
XDocument document = XDocument.Load(Server.MapPath("~/Releases_files/releases.xml"));
foreach (XElement element in document.Descendants("Release"))
{
TreeNode n0 = new TreeNode();
XName name0 = "version";
XAttribute a0 = element.Attribute(name0);
string temp0 = a0.Value;
n0.Text = temp0;
TreeView1.Nodes.Add(n0);
foreach (XElement myElement in element.Descendants("Feature"))
{
TreeNode n = new TreeNode();
XName name = "Name";
XAttribute a = myElement.Attribute(name);
string temp = a.Value;
n.Text = temp;
n0.ChildNodes.Add(n);
}
}
}
//action to do when selected node is changed
protected void TreeView1_SelectedNodeChanged(object sender, EventArgs e)
{
XDocument document = XDocument.Load(Server.MapPath("~/Releases_files/releases.xml"));
//debug
//Label1.Text = TreeView1.SelectedNode.Text;
//Label5.Text = Convert.ToString(TreeView1.SelectedNode.Depth);
//case1: feature selected
if (TreeView1.SelectedNode.Depth > 0)
{
string featureName = TreeView1.SelectedNode.Text;
string releaseName = TreeView1.SelectedNode.Parent.Text;
foreach (XElement element in document.Descendants("Release"))
{
//find the right release in XML
XName name = "version";
XAttribute a = element.Attribute(name);
string versionAttribute = a.Value;
if (releaseName.Equals(versionAttribute))
{
foreach (XElement myElement in element.Descendants("Feature"))
{
//find the right feature in XML
XName name1 = "Name";
XAttribute a1 = myElement.Attribute(name1);
string versionAttribute1 = a1.Value;
if (featureName.Equals(versionAttribute1))
{
//found the right node, now populate the Fields
IEnumerable<XElement> dates = element.Descendants("Date");
XElement date = dates.First<XElement>();
Label5.Text = date.Value;
IEnumerable<XElement> statuses = element.Descendants("Status");
XElement status = statuses.First<XElement>();
Label6.Text = status.Value;
IEnumerable<XElement> types = myElement.Descendants("Type");
XElement type = types.First<XElement>();
Label7.Text = type.Value;
IEnumerable<XElement> developers = myElement.Descendants("Developer");
XElement developer = developers.First<XElement>();
Label8.Text = developer.Value;
IEnumerable<XElement> details = myElement.Descendants("Detail");
XElement detail = details.First<XElement>();
tb.Text = detail.Value;
}
}
}
}
}
//case2: Release selected
else
{
string releaseName = TreeView1.SelectedNode.Text;
foreach (XElement element in document.Descendants("Release"))
{
//find the right release in XML
XName name = "version";
XAttribute a = element.Attribute(name);
string versionAttribute = a.Value;
if (releaseName.Equals(versionAttribute))
{
//found the right node, now populate the Fields
IEnumerable<XElement> dates = element.Descendants("Date");
XElement date = dates.First<XElement>();
Label5.Text = date.Value;
IEnumerable<XElement> statuses = element.Descendants("Status");
XElement status = statuses.First<XElement>();
Label7.Text = " ";
Label8.Text = " ";
tb.Text = " ";
}
}
}
}
#endregion
#region userInputs
protected void Button2_Click(object sender, EventArgs e)
{
}
//edit tree check box
protected void CheckBox1_CheckedChanged(object sender, EventArgs e)
{
if (CheckBox1.Checked )//&& TreeView1.Visible==true)
{
TreeView1.Visible = false;
if (m_pTreeView != null)
{
m_pTreeView.Visible = true;
}
Label5.Enabled = false;
Label6.Enabled = false;
Label7.Enabled = false;
Label8.Enabled = false;
tb.Enabled = false;
}
else
{
TreeView1.Visible = true;
if (m_pTreeView != null)
{
m_pTreeView.Visible = false;
}
Label5.Enabled = true;
Label6.Enabled = true;
Label7.Enabled = true;
Label8.Enabled = true;
tb.Enabled = true;
}
}
#endregion
}
}