所以我试图动态地添加和删除页面上的用户控件,详细说明我在网上找到的一个示例,该示例显示了如何动态添加用户控件。但我似乎无法让删除工作正常。我遵循的程序大致是......
在主页面中,单击添加按钮时,我创建了一个用户控件并将其deleteBtnClk
事件实例分配给方法deleteBtn_Click(object sender, EventArgs e)
,我将其传递给方法ucSimpleControl_deleteBtnClk
来自后面的主页代码
protected void btnAddControl_Click(object sender, EventArgs e)
{
// Create instance of the UserControl SimpleControl
usercontrols.SimpleControl ucSimpleControl =
LoadControl("~/usercontrols/SimpleControl.ascx")
as usercontrols.SimpleControl;
... ... ...
ucSimpleControl.deleteBtnClk +=
new usercontrols.deleteBtn_Click(ucSimpleControl_deleteBtnClk);
我也这样做是代码隐藏方法CreateUserControl(string controlID)
,它是从OnPreInit
方法调用的......
protected override void OnPreInit(EventArgs e)
{
...
...
...
if ((control != null && control.ClientID ==
btnAddControl.ClientID) || createAgain)
{
...
...
...
CreateUserControl(controlID);
}
我的用户控件中的删除按钮的OnClick方法设置为deleteBtn_Click
protected void deleteBtn_Click(object sender, EventArgs e)
{
onDelBtnClk(e);
}
调用虚拟方法onDelBtnClk
protected virtual void onDelBtnClk(EventArgs e)
{
deleteBtnClk(this, e);
}
并将此事件和eventargs传递给委托,该委托将用户控件创建和呈现分配给方法后面的方法ucSimpleControl_deleteBtnClk
void ucSimpleControl_deleteBtnClk(object sender, EventArgs e)
{
usercontrols.SimpleControl ucSimpleControl =
((usercontrols.SimpleControl)(sender));
ucSimpleControl.Parent.Controls.Remove(ucSimpleControl);
Session.Remove((ucSimpleControl.Num).ToString());
CreateUserControl(controlID);
}
在这里,我尝试通过获取父控件并使用sender用户控件作为参数调用Controls.Remove方法来删除用户控件。然后,我从Session中删除与用户控件关联的键值对,最后再次调用CreateUserControl以在Session中呈现所有用户控件。但行为很奇怪,只删除了最近创建的用户控件,而不是与单击删除按钮相关联的用户控件,并且在删除一个用户控件后,我无法添加超过当时存在的用户控件数量这页纸。比如,例如,如果页面上有5个用户控件,并且我删除了一个,那么尝试添加更多,我将无法添加超过5,尽管我应该能够添加无限多。这是完整的来源......
DisplayPage.aspx.cs
namespace UserControls4
{
public partial class DisplayPage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnAddControl_Click(object sender, EventArgs e)
{
// Create instance of the UserControl SimpleControl
usercontrols.SimpleControl ucSimpleControl =
LoadControl("~/usercontrols/SimpleControl.ascx")
as usercontrols.SimpleControl;
// Set the Public Properties
ucSimpleControl.FirstName.Text = "Milind";
ucSimpleControl.LastName.Text = "Chavan";
//Create Event Handler for btnPost Click
ucSimpleControl.btnPostClk +=
new usercontrols.btnPost_Click(ucSimpleControl_btnPostClk);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
ucSimpleControl.deleteBtnClk +=
new usercontrols.deleteBtn_Click(ucSimpleControl_deleteBtnClk);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Add the SimpleControl to Placeholder
Placeholder1.Controls.Add(ucSimpleControl);
// Add the instance of the SimpleControl to Session Variable
Session.Add((Session.Count + 1).ToString(), ucSimpleControl);
// Set createAgain = true
createAgain = true;
}
void ucSimpleControl_btnPostClk(object sender, EventArgs e)
{
usercontrols.SimpleControl ucSimpleControl =
((usercontrols.SimpleControl)(sender));
lblUser.Text = "Welcome " + ucSimpleControl.FirstName.Text +
" " + ucSimpleControl.LastName.Text;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
void ucSimpleControl_deleteBtnClk(object sender, EventArgs e)
{
usercontrols.SimpleControl ucSimpleControl =
((usercontrols.SimpleControl)(sender));
ucSimpleControl.Parent.Controls.Remove(ucSimpleControl);
Session.Remove((ucSimpleControl.Num).ToString());
CreateUserControl(controlID);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
// Declare 2 variable to handle user control after postback
const string controlID = "MyUserControl";
static bool createAgain = false;
protected Control GetPostBackControl(Page page)
{
Control control = null;
try
{
string ctrlName = page.Request.Params.Get("__EVENTTARGET");
if (ctrlName != null && ctrlName != String.Empty)
{
control = page.FindControl(ctrlName);
}
else
{
ContentPlaceHolder cph =
(ContentPlaceHolder)page.FindControl("Main");
for (int i = 0, len = page.Request.Form.Count; i < len; i++)
{
string[] ctl = page.Request.Form.AllKeys[i].Split('$');
if (ctl.Length > 3)
{
control = cph.FindControl(ctl[2])
as System.Web.UI.WebControls.Button;
}
if (control != null) break;
}
}
}
catch (Exception ex)
{
throw ex;
}
return control;
}
protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
Control control = GetPostBackControl(this.Page);
// Check if the postback is caused by the button
// Titled "Click to Create a Dynamic Control"
// OR
// createAgain field is true
// which means a call is made to the server while the
// user control is active
if ((control != null && control.ClientID ==
btnAddControl.ClientID) || createAgain)
{
//should be set before the CreateUserControl method
createAgain = true;
CreateUserControl(controlID);
}
}
protected void CreateUserControl(string controlID)
{
// createAgain field is set to true in the OnPreInit method
// when the 'Create User Control' button is clicked
// the createAgain field is used to check if the
// user control is on the page before the call
// if so create the control again and add it to the
// Control Hierarchy again
try
{
if (createAgain && Placeholder1 != null)
{
if (Session.Count > 0)
{
Placeholder1.Controls.Clear();
int simpleControlCount = 0;
for (int i = 0; i < Session.Count; i++)
{
switch (Session[i].ToString())
{
case "ASP.usercontrols_simplecontrol_ascx":
{
// Keep count of all SimpleControls
simpleControlCount++;
// Create instance of the UserControl SimpleControl
usercontrols.SimpleControl ucSimpleControl =
LoadControl("~/usercontrols/SimpleControl.ascx")
as usercontrols.SimpleControl;
// Set the Public Properties
ucSimpleControl.FirstName.Text =
((usercontrols.SimpleControl)(Session[i])).FirstName.Text;
ucSimpleControl.LastName.Text =
((usercontrols.SimpleControl)(Session[i])).LastName.Text;
ucSimpleControl.Num = simpleControlCount;
//Create Event Handler for btnPost Click
ucSimpleControl.btnPostClk +=
new usercontrols.btnPost_Click(ucSimpleControl_btnPostClk);
/////////////////////////////////////////////////////////////////////////////////////////////////////////
ucSimpleControl.deleteBtnClk +=
new usercontrols.deleteBtn_Click(ucSimpleControl_deleteBtnClk);
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//Add the SimpleControl to Placeholder
Placeholder1.Controls.Add(ucSimpleControl);
break;
}
}
}
}
}
}
catch (Exception ex)
{
throw ex;
}
}
}
}
DisplayPage.aspx
<head id="Head1" runat="server">
<title>This is example of how to add usercontrol dynamically</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="btnAddControl" runat="server"
Text="Click to add SimpleControl"
onclick="btnAddControl_Click" />
<br />
<asp:PlaceHolder runat="server"
ID="Placeholder1" ></asp:PlaceHolder>
<br />
<asp:Label ID="lblUser"
runat="server"></asp:Label>
</div>
</form>
</body>
</html>
SimpleControl.ascx.cs
namespace UserControls4.usercontrols
{
public delegate void btnPost_Click(object sender, System.EventArgs e);
public delegate void deleteBtn_Click(object sendre, System.EventArgs e);
public partial class SimpleControl : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}
private int num;
#region Public Event
public event btnPost_Click btnPostClk;
public event deleteBtn_Click deleteBtnClk;
#endregion
#region Public Properties
public TextBox FirstName
{
get
{
return txtFirstName;
}
set
{
txtFirstName = value;
}
}
public TextBox LastName
{
get
{
return txtLastName;
}
set
{
txtLastName = value;
}
}
public int Num
{
get { return this.num; }
set { this.num = value; }
}
#endregion
#region Vitual Methods
protected virtual void OnbtnDelQtnMrClk(EventArgs e)
{
// Call btnPost_Click event delegate instance
btnPostClk(this, e);
}
/// ///////////////////////////////////////////////////////////////////////////////////////
protected virtual void onDelBtnClk(EventArgs e)
{
deleteBtnClk(this, e);
}
/// /////////////////////////////////////////////////////////////////////////////////////////
#endregion
protected void btnPost_Click(object sender, EventArgs e)
{
//Call Virtual Method
OnbtnDelQtnMrClk(e);
}
///////////////////////////////////////////////////////////////////////////////////////////
protected void deleteBtn_Click(object sender, EventArgs e)
{
onDelBtnClk(e);
}
}
}
SimpleControl.ascx
<table>
<tr>
<td><asp:Label ID="label1" runat="server"
Text="First Name" ></asp:Label></td>
<td> <asp:TextBox ID="txtFirstName"
runat="server"></asp:TextBox></td>
</tr>
<tr>
<td><asp:Label ID="label2" runat="server"
Text="Last Name" ></asp:Label></td>
<td> <asp:TextBox ID="txtLastName"
runat="server"></asp:TextBox></td>
</tr>
<tr>
<td><asp:Button ID="btnPost" runat="server"
Text="Send Info" OnClick="btnPost_Click" />
</td>
</tr>
</table>
<obout:SuperForm ID="UserControlSuperForm"
Width="630" Title="SuperForm"
AutoGenerateRows="false"
RunAt="server"
DefaultMode="Insert"
FolderStyle="styles/black_glass">
<Fields>
<obout:TemplateField HeaderText="SuperForm">
<EditItemTemplate>
<asp:TextBox ID="superFormTxt" runat="server"></asp:TextBox>
</EditItemTemplate>
</obout:TemplateField>
</Fields>
</obout:SuperForm>
<asp:Button ID="removeBtn" runat="server" Text="Remove" OnClick="deleteBtn_Click"/>
答案 0 :(得分:1)
除了El Ronnoco的评论之外,动态添加和删除控件要求在回发期间添加每个控件,但更重要的是,每个控件都有唯一的ID。 ASP.NET运行时按ID挂接事件,因此如果要添加的每个控件都没有唯一的ID,则不会触发事件。