这个问题让我无穷无尽!要求是Web表单(用C#/ ASP.Net Webforms编写),用户可以在其中添加和删除控件行,以添加相同类型的pf数据的多个实例。
此页面存在于一个更大的站点中,该站点具有MasterPages层次结构,因此我可能遇到MasterPages的困难......
我的问题是专门从这个"表"中删除一行。为了好或坏我把它建成一个面板,保持多个子面板。每个子面板代表我的"表"。
的一行我的addRow按钮完美运行。但deleteRow按钮以不同的方式失败,具体取决于我尝试处理它们的方式。
这是我的default.aspx(修剪到相关部分):
<%@ 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);
}
}
}
我尝试添加呈现的HTML,但是超过了新帖子的字符限制!
总结:
我理解为什么&#39; BtnDeleteRow_Click()&#39;处理程序没有按照我想要的方式工作,所以我转而使用&#39; __ doPostBack&#39;希望我能在页面生命周期的早期发现删除事件。我可以在Page_load中捕获它,我认为这是最佳点(我的ViewState已被加载,因此我可以访问我的行索引,但页面尚未呈现)。但由于我无法获得任何类型的对象引用被点击的实际按钮,我无法前进。当我到达Page_load时,我确实在&#39;请求[&#34; __ EVENTTARGET&#34;]&#39;中有正确的ID。
答案 0 :(得分:0)
如果我理解你的目标,我会考虑使用UpdatePanel中包含的ListView来实现这种功能。以下示例使用表,但如果没有它们,您可以根据需要格式化表单:
https://www.codeproject.com/Articles/44070/Insert-a-new-record-using-ListView-with-a-GridView