2017-11-07 7 views
-1

이 문제는 문제를 일으키지 않습니다! 요구 사항은 사용자가 동일한 유형의 pf 데이터의 여러 인스턴스를 추가하기위한 컨트롤 행을 추가 및 삭제할 수있는 웹 양식 (C#/ASP.Net Webform으로 작성)에 대한 것입니다.순차적으로 번호가 매겨진 컨트롤에 액세스하기 C# 코드 뒤

이 페이지는 내가 MasterPages 어려움으로 실행될 수 있도록 MasterPages의 계층 구조를 가지고 더 큰 사이트의 존재 ...

내 문제는이 "테이블"에서 행을 삭제 특별히입니다. 좋았던 것을 위해 또는 나는 병이 여러 패널을 가지고있는 패널로 만들었다. 각 하위 패널은 내 "테이블"의 한 행을 나타냅니다.

내 addRow 버튼이 완벽하게 작동합니다. 그러나 deleteRow 버튼은 어떻게 처리 할 것인가에 따라 다른 방식으로 실패합니다.

  • 삭제 버튼에 대한 EventHandler를 등록하면 이벤트가 실행되고 메모리에서 행이 삭제되지만 다른 버튼을 클릭 할 때까지 페이지에 남아 있습니다 (두 번째 PostBack 이벤트가 발생 함).
  • JavaScript __doPostBack 방식을 사용하면 내 Page_Load 메서드에서 이벤트에 액세스 할 수 있지만 삭제하려는 행에 대한 객체 참조를 가져올 수 없습니다!

    <%@ Page Title="Alumni Outreach" Language="C#" EnableViewState="true" MasterPageFile="~/components/navigation/sidebar.master" AutoEventWireup="true" CodeBehind="default.aspx.cs" Inherits="www.law.unc.edu.alumni.outreach.outreach2" %> 
    <%@ MasterType VirtualPath="~/components/navigation/sidebar.master"%> 
    
    <asp:Content ID="Content1" ContentPlaceHolderID="cphContent1" runat="server"> 
        <asp:Panel ID="pnlInformation" runat="server"> 
         <h1>Community Outreach 
         </h1> 
         <p> 
          <span class="carolinaBlue">Purpose:</span> To quantify the UNC School of Law's <span class="carolinaBlue">Legacy of Leadership 
          </span>via Carolina Law alumni's stories of service, volunteerism, and leadership across the state and nation. Information gathered will be utilized in a variety of Carolina Law communnications/marketing pieces (for instance, an online presence with interactive maps) designed to illustrate Carolina Law alumni's leadership in the communities where they live and work. 
         </p> 
        </asp:Panel> 
        <asp:Panel ID="pnlForm" runat="server"> 
    
    
         <h2>Volunteer Leadership Roles</h2> 
         <p> 
          Please share your commitment to community leadership by noting all organizations you have voluntarily served below. 
         </p> 
         <div style="display: inline-block;"> 
          <asp:Button ID="btnAddLeadershipRow" OnClick="BtnAddLeadershipRow_Click" Text="+" runat="server" /> 
         </div> 
         <div style="display: inline-block"> 
          <div style="display: inline-block; width: 6.5em; font: 700 1em Verdana,Arial,Sans-Serif !important">Region</div> 
          <div style="display: inline-block; width: 7em; font: 700 1em Verdana,Arial,Sans-Serif !important">Profit?</div> 
          <div style="display: inline-block; width: 20.5em; font: 700 1em Verdana,Arial,Sans-Serif !important">Organization</div> 
          <div style="display: inline-block; width: 14em; font: 700 1em Verdana,Arial,Sans-Serif !important">Position</div> 
         </div> 
         <asp:Panel ID="pnlLeadershipFields" runat="server"> 
          <!-- dynamically add controls here --> 
         </asp:Panel> 
    </asp:Content> 
    

    그리고 여기에 내하여 default.aspx.cs 파일의 관련 부분은 다음과 같습니다 :

    using System; 
    using System.Collections.Generic; 
    using System.Web.UI; 
    using System.Web.UI.WebControls; 
    using BusinessLogic.Alumni.Outreach; 
    using System.Text.RegularExpressions; 
    
    namespace www.law.unc.edu.alumni.outreach 
    { 
        [ViewStateModeById] 
        public partial class outreach2 : System.Web.UI.Page 
        { 
         private List<String> regions; 
         private List<String> profit; 
         private List<Button> _foundControls = new List<Button>(); 
    
         public outreach2() 
         { 
          regions = new List<string> { 
           "Local", 
           "State", 
           "National" 
          }; 
    
          profit = new List<string> { 
           "Non-Profit", 
           "For-Profit" 
          }; 
         } 
    
         protected int LeadershipControlsMaxIndex 
         { 
          get { 
           if (ViewState["LeadershipControlsMaxIndex"] == null) 
            ViewState.Add("LeadershipControlsMaxIndex", 0); 
           return (int)ViewState["LeadershipControlsMaxIndex"]; 
          } 
          set { 
           if (ViewState["LeadershipControlsMaxIndex"] == null) 
            ViewState.Add("LeadershipControlsMaxIndex", value); 
           else 
            ViewState["LeadershipControlsMaxIndex"] = value; 
          } 
         } 
    
         protected List<int> LeadershipControlsIndexes 
         { 
          get { 
           if (!(ViewState["LeadershipControlsIndexes"] is List<int>)) 
           { 
            ViewState["LeadershipControlsIndexes"] = new List<int>(); 
           } 
           return (List<int>)ViewState["LeadershipControlsIndexes"]; 
          } 
          set { ViewState["LeadershipControlsIndexes"] = value; } 
         } 
    
         // If this is the first time the user is visiting the page 
         // create one set of controls 
         protected void Page_Load(object sender, EventArgs e) 
         { 
          if (!Page.IsPostBack) 
          { 
           CreateLeadershipControl(); 
          } 
          else if (Page.IsPostBack) 
          { 
           // if I do: 
           // btnDelete.OnClientClick = "javascript:__doPostBack(\""+btnDelete.ID+"\",\"\")"; 
           // when creating the delete button I enter the following if 
           // clause but cannot get an object (or Control or Button) 
           // reference to the btnDelete, whether I use this.Form or 
           // pnlLeadershipFields in the call to FindChildControlsRecursive 
           if (Request["__EVENTTARGET"].Contains("btnLeadershipRowDelete")) 
           { 
            FindChildControlsRecursive(this.Form); 
            object btnDelete = _foundControls.Find(x => x.ID == Request["__EVENTTARGET"]); 
            DeleteControls(btnDelete); 
           } 
           RecreateLeadershipControls(); 
          } 
         } 
    
         public void FindChildControlsRecursive(Control control) 
         { 
          foreach (Control childControl in control.Controls) 
          { 
           if (childControl.GetType() == typeof(Button)) 
           { 
            _foundControls.Add((Button)childControl); 
           } 
           else 
           { 
            FindChildControlsRecursive(childControl); 
           } 
          } 
         } 
    
         private void CreateLeadershipControl() 
         { 
          LeadershipControlsMaxIndex++; 
          LeadershipControlsIndexes.Add(LeadershipControlsMaxIndex - 1); 
          AddLeadershipControls(LeadershipControlsIndexes[LeadershipControlsIndexes.Count - 1]); 
         } 
    
         private void RecreateLeadershipControls() 
         { 
          List<int> indexes = LeadershipControlsIndexes; 
    
          for (int i = 0; i < indexes.Count; i++) 
          { 
           AddLeadershipControls(indexes[i]); 
          } 
         } 
    
         private void AddLeadershipControls(int index) 
         { 
          Panel pnlLeadershipControls = new Panel 
          { 
           ID = "LeadershipControls" + index.ToString(), 
           CssClass = "pnlControls" 
          }; 
    
          Button btnDelete = new Button() 
          { 
           ID = "btnLeadershipRowDelete" + index.ToString(), 
           Text = "-" 
          }; 
          //btnDelete.Click += new EventHandler(BtnDeleteRow_Click); 
          btnDelete.OnClientClick = "javascript:__doPostBack(\""+btnDelete.ID+"\",\"\")"; 
          btnDelete.Attributes.Add("style", "display: inline-block; width: 1.4em;"); 
          pnlLeadershipControls.Controls.Add(btnDelete); 
    
          DropDownList ddlRegion = new DropDownList 
          { 
           DataSource = regions, 
           ID = "LeadershipRegion" + index.ToString() 
          }; 
          ddlRegion.DataBind(); 
          ddlRegion.Attributes.Add("style", "display: inline-block; width: 7em;"); 
          pnlLeadershipControls.Controls.Add(ddlRegion); 
    
          DropDownList ddlProfit = new DropDownList 
          { 
           DataSource = profit, 
           ID = "LeadershipProfit" + index.ToString(), 
           CssClass = "ddlProfit" 
          }; 
          ddlProfit.DataBind(); 
          ddlProfit.Attributes.Add("style", "display: inline-block; width: 7.5em;"); 
          pnlLeadershipControls.Controls.Add(ddlProfit); 
    
          TextBox txtOrg = new TextBox 
          { 
           ID = "txtLeadershipOrganization" + index.ToString() 
          }; 
          txtOrg.Attributes.Add("style", "display: inline-block; width: 20em;"); 
          pnlLeadershipControls.Controls.Add(txtOrg); 
    
          TextBox txtPos = new TextBox 
          { 
           ID = "txtLeadershipPosition" + index.ToString() 
          }; 
          txtPos.Attributes.Add("style", "display: inline-block; width: 20em;"); 
          pnlLeadershipControls.Controls.Add(txtPos); 
    
          CheckBox cbCurrent = new CheckBox 
          { 
           ID = "cbLeadershipCurrent" + index.ToString(), 
           Text = "Current?", 
          }; 
          cbCurrent.Attributes.Add("style", "display: inline-block; font: 700 1em Verdana,Arial,Sans-Serif !important"); 
          pnlLeadershipControls.Controls.Add(cbCurrent); 
    
          pnlLeadershipFields.Controls.Add(pnlLeadershipControls); 
         } 
    
    
         private void DeleteControls(object sender) 
         { 
          Button button = (Button)sender; 
          string id = button.ID; 
          int index = Int32.Parse(Regex.Match(id, @"\d+$").Value); 
          Panel row = (Panel)button.Parent; 
    
          for (int i = row.Controls.Count - 1; i >= 0; i--) 
          { 
           if (row.Controls[i] is Button) 
            ((Button)row.Controls[i]).Click -= new EventHandler(BtnDeleteRow_Click); 
           row.Controls[i].Dispose(); 
          } 
          row.Parent.FindControl(row.ID).Dispose(); 
          if (id.Contains("Leadership")) 
          { 
           LeadershipControlsIndexes.RemoveAt(LeadershipControlsIndexes.FindIndex(x => x == index)); 
          } 
         } 
    
         protected void BtnAddLeadershipRow_Click(object sender, EventArgs e) 
         { 
          CreateLeadershipControl(); 
         } 
    
         // If I do: 
         // btnDelete.Click += new EventHandler(BtnDeleteRow_Click); 
         // when creating the delete button, this method is called, 
         // but too late in the page life cycle 
         protected void BtnDeleteRow_Click(object sender, EventArgs e) 
         { 
          DeleteControls(sender); 
         } 
        } 
    } 
    

    내가 여기

내 (관련 부분에 트리밍) default.aspx에있다 렌더링 된 HTML을 추가하려고했지만 새 글자 수를 초과했습니다. 요약

:

이 이해가 왜 'BtnDeleteRow_Click은() 핸들러는 내가 원하는 방식으로 작동하지 않는, 그래서 내가 삭제 이벤트를 잡을 수있는 희망의'__doPostBack '를 사용으로 전환 페이지 수명주기의 초기 단계 나는 Page_load에서 그것을 잡을 수 있는데, 나는 달콤한 자리라고 생각한다. (내 ViewState가로드되어서 내 행 인덱스에 액세스 할 수 있지만 페이지는 렌더링되지 않았다.) 그러나 나는 클릭 한 실제 버튼에 대한 어떤 종류의 객체 참조도 얻을 수 없으므로 앞으로 나아갈 수 없습니다. Page_load에 도착하면 'Request [ "EVENTTARGET"]'에 올바른 ID가 있습니다.

+0

을도 코멘트하지 않고 내 질문에 투표 한 익명의 유권자에 - 나는 내 문제를 연구 어제의 대부분을 보냈다 유용한 결과가 없기 때문에 여러 가지 방법을 시도하여 혼자서 해결했으며 마지막으로 누군가가 유용한 제안을하기를 희망하여 게시했습니다. – cptully

답변

0

내가 당신의 목표를 이해한다면, 나는 이런 종류의 기능을 위해 UpdatePanel에 싸여진 ListView를 사용하는 것을 고려할 것이다. 다음 예는 테이블을 사용하지만, 그들없이 양식을 포맷 할 수 있습니다 어쨌든 당신이 좋아하는 것 :

https://www.codeproject.com/Articles/44070/Insert-a-new-record-using-ListView-with-a-GridView

+0

안녕하세요, StackOverflow에 오신 것을 환영합니다! 링크 된 페이지의 좀 더 자세한 내용을 답안에 포함시켜주십시오. 링크 된 답변은 일반적으로 링크 된 페이지가 제거되고 정보가 손실 될 수 있으므로 권장하지 않습니다. –

+0

안녕하세요. Ben, 코드 샘플이 너무 길어서 여기에 인용 할 수 없을 것 같습니까? –

+0

내 목표는 표와 같은 외관을 갖는 것입니다. 셀 중 하나 또는 두 개가 드롭 다운이고 두 개는 텍스트 편집이며 마지막 셀은 체크 박스입니다.내가 사용한 중첩 된 패널은 꽤 좋지 않을 수도 있지만 작동하며 위에서 말했듯이 삭제 버튼이 작동합니다 (하지만 효과를 분명히 알기 위해서는 페이지를 새로 고쳐야합니다). 아직 ListView의 UpdatePanels로 작업 했으므로 신중하게 참조한 게시물을 읽어야합니다. – cptully