そのため、ユーザーコントロールを動的に追加する方法を示すオンラインで見つけた例を詳しく説明することにより、ページ上のユーザーコントロールを動的に追加および削除しようとしています。しかし、削除が適切に機能していないようです。私が従う手順は大まかに.....
メイン ページで、追加ボタンがクリックされると、ユーザー コントロールを作成し、その
deleteBtnClk
イベント インスタンスを methodに割り当てます。このメソッドに、メイン ページのコード ビハインドから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);
}
ここでは、親コントロールを取得し、送信者ユーザー コントロールを引数として Controls.Remove メソッドを呼び出して、ユーザー コントロールを削除しようとしています。次に、ユーザー コントロールに関連付けられているキーと値のペアをセッションから削除し、最後に CreateUserControl を再度呼び出して、セッション内のすべてのユーザー コントロールをレンダリングします。しかし、動作は奇妙です。最後に作成されたユーザーコントロールのみが削除され、クリックされた削除ボタンに関連付けられたユーザーコントロールは削除されません。また、1つのユーザーコントロールを削除した後、その時点で存在するユーザーコントロールの数を超えて追加することはできませんページ。たとえば、ページに 5 つのユーザー コントロールがあり、1 つを削除してさらに追加しようとすると、無限に多く追加できるはずですが、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"/>