2010-08-05 87 views
0

我想動態地添加控件到一個asp.net頁面。該頁面被正確渲染,但回發後,我收到以下錯誤:使用多個ASP.NET控件具有相同的ID

[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 

我嘗試了好幾種不同的東西沒有一個工作。我以爲在OnInit中或在這樣

Control c = Page.FindControl("ParentTextBox_ChildTextBox_TV_PostRender"); 
Page.Controls.Remove(c); 

Page_Load中刪除控制工作,但它並不

定製樹型控件的代碼

// 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); 
     } 
    } 
} 

這是我的頁面添加樹:

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 

    } 
} 
+1

更多代碼請(尤其是aspx) – 2010-08-05 18:23:05

+0

什麼版本的.NET 2.0或4.0? – Jake1164 2010-08-05 18:23:53

+0

aspx中沒有任何東西,我從aspx.cs – nooob 2010-08-05 18:24:07

回答

2

您需要將控件的ID屬性設置爲某種唯一值添加到頁面之前。有很多技巧可以用來完成這項工作。如果您提供更多的代碼,我們可以提供適合您情況的解決方案。

編輯

看起來你已經有了一些非常複雜的東西會在這裏,所以我不完全所著的Grokking它。但是,我會在實例化ContainerTreeNodes時設置它們的ID,而不是在OnInit階段。我還會讓ContainerTreeNode體系結構支持遍歷和刪除其中的節點,而不是嘗試從樹外部基於Control ID手動刪除節點。

+1

+1中增加了一個自定義treeview,用於grokking的使用。真棒的話 – Jonathan 2013-03-06 19:41:27

2

我可能會誤解代碼,但如果PreRenderContainer和PostRenderContainer屬性實現INamingcontainer並且您更改了它們的ID,我認爲您可能不會讓它們完成工作。它應該會自動給你唯一的ID。像ctl00,ctl01等...

相關問題