[英]Adding Dynamic Controls in ASP.NET
在我看來,在ASP.NET Web窗體中動態添加控件存在固有的困難。 具體來說,要使動態添加的控件包含在ViewState
,並正確地Page_PreInit
事件等,建議在Page_PreInit
事件期間添加這些Page_PreInit
。
也就是說,很多時候我們可能想根據事件(例如用戶單擊按鈕)添加此類控件。 諸如Click事件之類的控件特定事件始終在Init之后甚至在Load之后運行。 假設以下.aspx ....
<form id="form1" runat="server">
<div>
<asp:PlaceHolder ID="phAddresses" runat="server"></asp:PlaceHolder>
<br /><br />
<asp:Button ID="btnAddAddress" runat="server" Text="Add Another Address" OnClick="btnAddAddress_Click" />
...以及以下.aspx.cs ....
private static List<AddressUserControl> addresses = new List<AddressUserControl>();
protected void Page_PreInit(object sender, EventArgs e)
{
foreach (AddressUserControl aCntrl in addresses)
{
phAddresses.Controls.Add(aCntrl);
// Helper to find button within user control
addressButtonControl = findAddressControlRemoveButton(aCntrl);
addressUserControlButton.ID = "btnRemoveAddress" + addressCount;
addressUserControlButton.Click += new EventHandler(addressUserControlButton_Click);
addressCount++;
}
}
protected void btnAddAddress_Click(object sender, EventArgs e)
{
AddressUserControl aCntrl = LoadControl("~/UserControls/AddressUserControl.ascx") as AddressUserControl;
addresses.Add(aCntrl);
}
現在,在上述情況下,顯示的用戶控件數始終落后於用戶實際添加的數量,因為Click事件要到PreInit之后才運行,在PreInit之后必須將控件添加到占位符。 我必須在這里遺漏一些東西,因為這似乎是ASP生命周期所固有的,並且需要一些“ hack”或其他。
編輯-是的,由於某些原因,我在btnAddress_Click()期間添加的EventHandlers將無法運行,只有我在Page_Init期間或以聲明方式在標記中添加的EventHandlers無法運行。 這就是我試圖做的...
protected void btnAddAddress_Click(object sender, EventArgs e)
{
AddressUserControl aCntrl = LoadControl("~/UserControls/AddressUserControl.ascx") as AddressUserControl;
addresses.Add(aCntrl);
phAddresses.Controls.Add(aCntrl);
findAddressControlRemoveButton(aCntrl);
addressUserControlButton.ID = "btnRemoveAddress" + addresses.Count;
///////////////////////////////////////////////////////////////////////////////////
// ADDED EVENT HANDLER HERE
//////////////////////////////////////////////////////////////////////////////////////
addressUserControlButton.Click += new E ventHandler(addressUserControlButton_Click);
}
...但事件不會像我所說的那樣觸發。 有任何想法嗎?
編輯-這是我的AddressUserControl的標記。 文件背后的代碼中沒有邏輯
<%@ Control Language="C#" ClassName="AddressUserControl" AutoEventWireup="true" CodeBehind="AddressUserControl.ascx.cs" Inherits="XFAWithUserControl.UserControls.AddressUserControl" %>
<asp:Panel ID="pnlAddressForm" runat="server">
<asp:Label ID="lblStreet" runat="server" Text="Street Address"></asp:Label>
<asp:TextBox ID="txtStreet" runat="server"></asp:TextBox>
<br /><br />
<asp:Label ID="lblCity" runat="server" Text="City"></asp:Label>
<asp:TextBox ID="txtCity" runat="server"></asp:TextBox>
<br /><br />
<asp:Label ID="lblState" runat="server" Text="State"></asp:Label>
<asp:TextBox ID="txtState" runat="server"></asp:TextBox>
<br /><br />
<asp:Label ID="lblZip" runat="server" Text="Zip"></asp:Label>
<asp:TextBox ID="txtZip" runat="server"></asp:TextBox>
<br /><br />
<asp:Button ID="btnRemoveAddress" runat="server" Text="Remove Address" />
</asp:Panel>
現在我對btnRemoveAddress的點擊事件只是這樣的愚蠢...
private void addressUserControlButton_Click(object sender, EventArgs e)
{
Button thisButton = sender as Button;
thisButton.Text = "Why Hello";
}
但是我的目標是讓它刪除關聯的AddressUserControl,以便用戶可以通過單擊按鈕從頁面添加和/或刪除任意數量的AddressUserControls。
編輯-這是我現在所擁有的,仍然無法正常工作
protected void btnAddAddress_Click(object sender, EventArgs e)
{
AddressUserControl aCntrl = LoadControl("~/UserControls/AddressUserControl.ascx") as AddressUserControl;
addresses.Add(aCntrl);
phAddresses.Controls.Add(aCntrl);
findAddressControlRemoveButton(aCntrl);
addressUserControlButton.ID = "btnRemoveAddress" + addresses.Count;
aCntrl.ChangeText += new EventHandler(addressUserControlButton_Click);
}
private void addressUserControlButton_Click(object sender, EventArgs e)
{
Button thisButton = sender as Button;
thisButton.Text = "Why Hello";
}
AddressUserControl.ascx
<asp:Panel ID="pnlAddressForm" runat="server">
<asp:Label ID="lblStreet" runat="server" Text="Street Address"></asp:Label>
<asp:TextBox ID="txtStreet" runat="server"></asp:TextBox>
<br /><br />
<asp:Label ID="lblCity" runat="server" Text="City"></asp:Label>
<asp:TextBox ID="txtCity" runat="server"></asp:TextBox>
<br /><br />
<asp:Label ID="lblState" runat="server" Text="State"></asp:Label>
<asp:TextBox ID="txtState" runat="server"></asp:TextBox>
<br /><br />
<asp:Label ID="lblZip" runat="server" Text="Zip"></asp:Label>
<asp:TextBox ID="txtZip" runat="server"></asp:TextBox>
<br /><br />
<asp:Button ID="btnRemoveAddress" runat="server" Text="Remove Address" OnClick="btnRemoveAddress_Click" />
</asp:Panel>
AddressUserControl.ascx.cs
public event EventHandler ChangeText;
protected void Page_Load(object sender, EventArgs e)
{
}
public void btnRemoveAddress_Click(object sender, EventArgs e)
{
if (this.ChangeText != null)
{
ChangeText(sender, e);
}
}
您需要將點擊處理程序中的邏輯添加到面板的Controls
集合以及控件列表中,如下所示:
protected void btnAddAddress_Click(object sender, EventArgs e)
{
AddressUserControl aCntrl = LoadControl("~/UserControls/AddressUserControl.ascx") as AddressUserControl;
addresses.Add(aCntrl);
phAddresses.Controls.Add(aCntrl);
}
更新:
在用戶控件中,您需要定義一個事件,該事件可以在承載用戶控件的頁面中定義,如下所示:
AddressUserControl.cs(代碼隱藏):
public event EventHandler RemoveAddress;
protected void removeAddressUserControlButton_Click(object sender, EventArgs e)
{
// Find out if the event has been set, if so then call it
if (this.RemoveAddress!= null)
{
RemoveAddress(sender, e);
}
}
現在,在您使用用戶控件的頁面上,執行以下操作:
// Wire up the user control's event
nameOfUserControl.RemoveAddress += new EventHandler(addressUserControlButton_Click);
最后,實現addressUserControlButton_Click
事件:
protected void addressUserControlButton_Click(object sender, EventArgs e)
{
// Do your dynamic control creation here or whatever else you want on the page
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.