2009-08-29 2 views
0

동적으로 생성 된 테이블/컨트롤에 문제가 있습니다. 나는 몇 가지 해결책을 찾기 위해 interwebs를 검색해 보았지만 몇 가지 시도를했지만 아래의 코드를 보지 못한 이유가 무엇인지에 대해 시도했습니다.동적 컨트롤 - 동일한 ID를 가진 여러 컨트롤

필자는 필 요할 때 새로운 열을 추가 한 다음 테이블을 다시로드하고 동적으로 생성 된 열을 제거 할 수 있기를 원합니다. 그런 다음 동적으로 생성 된 셀의 값을 가져 오기 위해 다시 게시를하고 싶습니다. 매우 간단합니다. 여기

코드입니다 :

using System; 
using System.Collections; 
using System.Configuration; 
using System.Data; 
using System.Web; 
using System.Web.Security; 
using System.Web.UI; 
using System.Web.UI.HtmlControls; 
using System.Web.UI.WebControls; 
using System.Web.UI.WebControls.WebParts; 
using System.Text; 

namespace TimeTracker 
{ 
    public partial class _Default : System.Web.UI.Page 
    { 


     private int NumberofRows 
     { 
      get 
      { 
       object o = ViewState["NumberofRows"]; 
       if (o == null) return 4; 
       return (int)o; 
      } 
      set 
      { 
       ViewState["NumberofRows"] = value; 
      } 
     } 

     protected void Page_Load(object sender, EventArgs e) 
     { 
      //if (!Page.IsPostBack) 
      //{ 
       CreateBigTestTable(); 
      //} 
     } 

     /// <summary> 
     /// 
     /// </summary> 
     protected void CreateBigTestTable() 
     { 
      Table1.Controls.Clear(); 
      DataTable dt; 

      if (Cache["GetData"] != null) 
      { 
       dt = (DataTable)Cache["GetData"]; 
      } 
      else 
      { 
       dt = GetData(); 
       Cache.Insert("GetData", dt, null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(20)); 
      } 

      int colSpan = dt.Rows.Count; 
      int rowCount = NumberofRows; 

      // Create a TableHeaderRow. 
      TableHeaderRow headerRow = new TableHeaderRow(); 
      headerRow.BackColor = System.Drawing.Color.AliceBlue; 

      // Create TableCell objects to contain the text for the header. 
      TableHeaderCell headerTableCell1 = new TableHeaderCell(); 
      TableHeaderCell headerTableCell2 = new TableHeaderCell(); 
      TableHeaderCell headerTableCell3 = new TableHeaderCell(); 
      headerTableCell1.Text = ""; 
      headerTableCell1.Scope = TableHeaderScope.Column; 
      headerTableCell1.AbbreviatedText = ""; 

      Label lblheaderTableCell2 = new Label(); 
      lblheaderTableCell2.Text = "Labor Category Hours"; 

      ImageButton imgBtnNew = new ImageButton(); 
      imgBtnNew.ImageUrl = "~/images/plus.gif"; 
      imgBtnNew.ImageAlign = ImageAlign.Top; 
      imgBtnNew.ID = "imgBtnNew"; 
      imgBtnNew.Click += new ImageClickEventHandler(imgBtnNew_Click); 

      headerTableCell2.Controls.Add(lblheaderTableCell2); 
      headerTableCell2.Controls.Add(imgBtnNew); 
      headerTableCell2.ColumnSpan = colSpan; 

      headerTableCell3.Text = "Total Hours"; 
      headerTableCell3.HorizontalAlign = HorizontalAlign.Right; 
      headerTableCell3.Scope = TableHeaderScope.Column; 
      headerTableCell3.AbbreviatedText = "Total Hours"; 
      headerTableCell3.ColumnSpan = 2; 

      headerRow.Cells.Add(headerTableCell1); 
      headerRow.Cells.Add(headerTableCell2); 
      headerRow.Cells.Add(headerTableCell3); 

      /// 
      ///Sub header row 
      /// 
      TableHeaderRow headerRow1 = new TableHeaderRow(); 
      headerRow1.BackColor = System.Drawing.Color.AliceBlue; 

      TableHeaderCell headerTableCell11 = new TableHeaderCell(); 
      TableHeaderCell headerTableCell22 = new TableHeaderCell(); 
      TableHeaderCell headerTableCell33 = new TableHeaderCell(); 
      TableHeaderCell headerTableCell44 = new TableHeaderCell(); 

      headerTableCell11.Text = "Functional Area"; 
      headerTableCell11.Scope = TableHeaderScope.Column; 
      headerTableCell11.AbbreviatedText = "Functional Area"; 
      headerTableCell11.Height = 100; 
      headerTableCell11.VerticalAlign = VerticalAlign.Bottom; 

      headerRow1.Cells.Add(headerTableCell11); 

      // Labor Category Title 
      foreach (DataRow dr in dt.Rows) 
      { 
       TableCell tempCell = new TableCell(); 

       Label lblLaborCategoryTitle = new Label(); 
       lblLaborCategoryTitle.Text = dr["Title"].ToString(); 
       tempCell.Controls.Add(lblLaborCategoryTitle); 

       ImageButton ctrl = new ImageButton(); 
       ctrl.ID = "dynamicImageButton" + dr["ID"].ToString(); 
       ctrl.ImageUrl = "~/images/delete.gif"; 
       ctrl.Click += new ImageClickEventHandler(img_Click); 

       tempCell.Controls.Add(ctrl); 

       headerRow1.Cells.Add(tempCell); 
      } 

      headerTableCell33.Text = "Current Period"; 
      headerTableCell33.HorizontalAlign = HorizontalAlign.Right; 
      headerTableCell33.Scope = TableHeaderScope.Column; 
      headerTableCell33.AbbreviatedText = "Current Period"; 
      headerTableCell33.Height = 100; 
      headerTableCell33.VerticalAlign = VerticalAlign.Top; 
      headerRow1.Cells.Add(headerTableCell33); 

      headerTableCell44.Text = "Cummulative"; 
      headerTableCell44.HorizontalAlign = HorizontalAlign.Right; 
      headerTableCell44.Scope = TableHeaderScope.Column; 
      headerTableCell44.AbbreviatedText = "Cummulative"; 
      headerTableCell44.Height = 100; 
      headerTableCell44.VerticalAlign = VerticalAlign.Top; 
      headerRow1.Cells.Add(headerTableCell44); 

      // Add the TableHeaderRow as the first item in the Rows collection of the table. 
      Table1.Rows.AddAt(0, headerRow); 
      Table1.Rows.AddAt(1, headerRow1); 

      /// 
      /// Add rows to the table. 
      /// 
      for (int rowNum = 0; rowNum < rowCount; rowNum++) 
      { 
       TableRow tempRow = new TableRow(); 

       // add cell for functional area 
       TableCell tempCellSpacer = new TableCell(); 
       tempCellSpacer.Text = "Functional Area: " + rowNum.ToString(); 
       tempRow.Cells.Add(tempCellSpacer); 

       for (int cellNum = 0; cellNum < colSpan; cellNum++) 
       { 
        TableCell tempCell = new TableCell(); 

        TextBox tb = new TextBox(); 
        tb.MaxLength = 128; 
        //tb.ID = "txt_Number" + cellNum.ToString(); 
        tb.Text = String.Format("({0},{1})", rowNum, cellNum); 
        tempCell.Controls.Add(tb); 
        tempRow.Cells.Add(tempCell); 
       } 

       // add cells for current period 
       TableCell tempCurrentPeriod = new TableCell(); 
       tempRow.Cells.Add(tempCurrentPeriod); 

       // add cells for Cummulative 
       TableCell tempCummulative = new TableCell(); 
       tempRow.Cells.Add(tempCummulative); 

       Table1.Rows.Add(tempRow); 
      } 

      /// 
      /// Create a TableFooterRow 
      /// 
      TableFooterRow footerRow = new TableFooterRow(); 
      footerRow.BackColor = System.Drawing.Color.AliceBlue; 

      // Create TableCell objects to contain the text for the footer. 
      TableCell footerTableCell1 = new TableCell(); 
      TableCell footerTableCell2 = new TableCell(); 
      TableCell footerTableCell3 = new TableCell(); 
      footerTableCell1.Text = "Total Amount"; 
      footerTableCell1.ColumnSpan = colSpan+1; 
      footerTableCell1.HorizontalAlign = HorizontalAlign.Right; 
      footerTableCell2.Text = "Column 2 footer"; 
      footerTableCell2.HorizontalAlign = HorizontalAlign.Right; 
      footerTableCell3.Text = "Column 3 footer"; 
      footerTableCell3.HorizontalAlign = HorizontalAlign.Right; 

      // Add the TableCell objects to the Cells collection of the TableFooterRow. 
      footerRow.Cells.Add(footerTableCell1); 
      footerRow.Cells.Add(footerTableCell2); 
      footerRow.Cells.Add(footerTableCell3); 

      // Add the TableFooterRow to the Rows collection of the table. 
      Table1.Rows.Add(footerRow); 
     } 

     /// <summary> 
     /// 
     /// </summary> 
     /// <param name="sender"></param> 
     /// <param name="e"></param> 
     protected void img_Click(object sender, ImageClickEventArgs e) 
     { 
      Response.Write("Test"); 
     } 

     /// <summary> 
     /// 
     /// </summary> 
     /// <param name="sender"></param> 
     /// <param name="e"></param> 
     protected void imgBtnNew_Click(object sender, ImageClickEventArgs e) 
     { 
      DataTable dt; 

      if (Cache["GetData"] != null) 
      { 
       dt = (DataTable)Cache["GetData"]; 
       dt.Rows.Add(new Object[] { 5, "Test" }); 
      } 
      else 
      { 
       dt = GetData(); 
       dt.Rows.Add(new Object[] { 5, "Test" }); 
       Cache.Insert("GetData", dt, null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(20)); 
      } 

      CreateBigTestTable(); 
     } 

     /// <summary> 
     /// 
     /// </summary> 
     /// <param name="sender"></param> 
     /// <param name="e"></param> 
     protected void btnUpdate_Click(object sender, EventArgs e) 
     { 
      ProcessControls(Table1); 
     } 

     /// <summary> 
     /// 
     /// </summary> 
     /// <param name="control"></param> 
     private void ProcessControls(Control control) 
     { 
      foreach (Control ctrl in control.Controls) 
      { 
       if (ctrl.GetType() == typeof(TextBox)) 
       { 
        Response.Write(string.Format("Control ID: {0} Text: {1}<br/>", ((TextBox)ctrl).ID, ((TextBox)ctrl).Text)); 
       } 

       if (ctrl.HasControls()) 
        ProcessControls(ctrl); 
      } 
     } 

     /// <summary> 
     /// 
     /// </summary> 
     /// <returns></returns> 
     private DataTable GetData() 
     { 
      DataTable dt = new DataTable(); 
      DataRow dr; 
      dt.Columns.Add(new System.Data.DataColumn("ID", typeof(String))); 
      dt.Columns.Add(new System.Data.DataColumn("Title", typeof(String))); 

      dr = dt.NewRow(); 
      dr[0] = "1"; 
      dr[1] = "Web Developer"; 
      dt.Rows.Add(dr); 

      dr = dt.NewRow(); 
      dr[0] = "2"; 
      dr[1] = "Project Manager"; 
      dt.Rows.Add(dr); 

      dr = dt.NewRow(); 
      dr[0] = "3"; 
      dr[1] = "System Analyst"; 
      dt.Rows.Add(dr); 

      dr = dt.NewRow(); 
      dr[0] = "4"; 
      dr[1] = "Database Administrator"; 
      dt.Rows.Add(dr); 

      return dt; 
     } 
    } 
} 
+0

내 문제가 해결되었습니다. ASPX 페이지에 ASP가 있고 자리 표시자가 없습니다. 내가 ASP를 제거 : 테이블과 자리 표시 자로 대체하고 테이블을 생성 할 때마다 컨트롤을 지우십시오. 이제 완벽하게 작동합니다. 도와 주셔서 감사합니다. – Todd

+0

나는 곧 말했다. ID 할당을 텍스트 상자에 주석 처리 했으므로 내가 제거했을 때 여전히 동일한 오류가 발생합니다. – Todd

+0

해결되었습니다. 텍스트 상자 ID에 대한 이름 지정 문제가 발생했습니다. 들리는 사내 주셔서 감사합니다. – Todd

답변

1

왜 그냥 당신의 버튼과 true로 설정 자동 생성 열에 대한 템플릿 열이있는 데이터 그리드를 사용하여 동적으로 열을 당신이에 바인딩하여 데이터 테이블을 추가하지. 그런 다음 다시 게시 할 때 onItemCommand를 사용하고 선택한 인덱스를 가져오고 findcontrol을 사용하여 새 컨트롤과 값을 찾습니다. 나는 내 댓글에서 언급 한 바와 같이

브라이언

+0

DataGrid 또는 gridview로 만들 수없는 사용자 정의 테이블 레이아웃입니다. – Todd

+0

@chopps : HTML과 CSS로 레이아웃을 만들 수 있다고 생각합니다. 적어도 수동으로 테이블을 만드는 대신 리피터 컨트롤 같은 기존 컨트롤을 사용합니다. – Juri

0

나는 당신이 기존의 닷넷 컨트롤 (및 CSS, 템플릿 및 적절한 HTML 코드)에 필요한 달성 할 수있을 것 같아요.

그렇지 않으면 생성 된 컨트롤의 ID 문제에 대해 추가 클래스를 만들 수 있습니다.이 클래스를 UniqueId라고 부르거나 공개 메서드 GetUniqueId(string)이있는 곳으로 만들 수 있습니다. UniqueId 클래스는 전달되어야하는 모든 ID를 기억하고 목록에 기록합니다.

public string GetUniqueId(string key) 
{ 
    //lookup "key" in a private list 
    //if the key is present, generate a random number, append it 
    //to "key", add it to the list for remembering it and return it 
} 

이러한 메소드는 항상 고유 한 ID를 확보해야합니다. 시도해 볼 수있는 것은 페이지의 OnInit 이벤트에서 큰 테이블 테스트를 만드는 것입니다. 컨트롤은 일반적으로 라이프 사이클의 해당 단계에서 컨트롤 컬렉션에 항상 추가되어야합니다.

0

우리는 직장에서 같은 문제가있었습니다. 내가이 문제를 해결하기 위해 한 일은 radGrid.MasterTableView.EnableColumnsViewState = false

이유는 RadGrid 때문에 동적 컨트롤의, 다시 게시 후 다시되었다는 것입니다 설정했다, 또한 열을 추가하려고 한 ViewState를했다. 열은 "이중화"되어 "동일한 ID를 가진 다중 컨트롤"오류가 발생합니다.