コントロール ツリーに動的コントロールを登録するには、Page_Load および Page_Init 内に動的コントロールを作成する必要があることを認識しています。
ボタンの OnClick イベントで ViewState を使用する必要があるカスタム コントロールを作成しました。この ViewState は、コントロールを動的に作成するために使用されます。
ライフサイクルは次のようになります: ページの読み込み -> ボタンのクリック -> ページのプリレンダー。ビューステートは「ボタン クリック」まで更新されないため、Page PreRender で動的コントロールを作成しています。ただし、ボタンを作成し、Page_PreRender で OnClick EventHandler をプログラムで割り当てることは機能しません。
これを機能させる方法を知っている人はいますか?
btn_DeleteTableRow_Click は起動しません。これは CreatePartRows() で設定されます
これが私の例です:
<asp:UpdatePanel ID="up_RMAPart" runat="server" UpdateMode="Conditional" EnableViewState="true" ChildrenAsTriggers="true">
<ContentTemplate>
<div class="button" style="width: 54px; margin: 0px; float: right;">
<asp:Button ID="btn_AddPart" runat="server" Text="Add" OnClick="btn_AddPart_Click" />
</div>
<asp:Table ID="Table_Parts" runat="server" CssClass="hor-zebra">
</asp:Table>
<div class="clear"></div>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btn_AddPart" EventName="Click" />
</Triggers>
コードビハインド:
[Serializable]
public struct Part
{
public string PartName;
public int Quantity;
public int PartID;
public Part(string sPartName, int iQuantity, int iPartID)
{
PartName = sPartName;
Quantity = iQuantity;
PartID = iPartID;
}
}
public partial class RMAPart : System.Web.UI.UserControl
{
private Dictionary<string,Part> m_RMAParts;
private int m_RowNumber = 0;
public Dictionary<string, Part> RMAParts
{
get
{
if (ViewState["m_RMAParts"] != null)
return (Dictionary<string, Part>)ViewState["m_RMAParts"];
else
return null;
}
set
{
ViewState["m_RMAParts"] = value;
}
}
public int RowNumber
{
get
{
if (ViewState["m_RowNumber"] != null)
return Convert.ToInt32(ViewState["m_RowNumber"]);
else
return 0;
}
set
{
ViewState["m_RowNumber"] = value;
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
RMAParts = new Dictionary<string, Part>();
RowNumber = 0;
RMAParts.Add("PartRow_" + RowNumber.ToString(), new Part());
RowNumber = 1;
CreatePartRows();
}
}
protected void Page_PreRender(object sender, EventArgs e)
{
CreatePartRows();
}
private void CreatePartRows()
{
Table_Parts.Controls.Clear();
TableHeaderRow thr = new TableHeaderRow();
TableHeaderCell thc1 = new TableHeaderCell();
thc1.Controls.Add(new LiteralControl("Part"));
thr.Cells.Add(thc1);
TableHeaderCell thc2 = new TableHeaderCell();
thc2.Controls.Add(new LiteralControl("Quantity"));
thr.Cells.Add(thc2);
TableHeaderCell thc3 = new TableHeaderCell();
thc3.Controls.Add(new LiteralControl(""));
thr.Cells.Add(thc3);
Table_Parts.Rows.Add(thr);
foreach (KeyValuePair<string, Part> kvp in RMAParts)
{
string[] sKey = kvp.Key.Split('_');
TableRow tr = new TableRow();
tr.ID = kvp.Key;
TableCell tc1 = new TableCell();
TextBox tb_Part = new TextBox();
tb_Part.ID = "tb_Part_" + sKey[1];
tb_Part.CssClass = "textbox1";
tc1.Controls.Add(tb_Part);
tr.Cells.Add(tc1);
TableCell tc2 = new TableCell();
TextBox tb_Quantity = new TextBox();
tb_Quantity.ID = "tb_Quanitty_" + sKey[1];
tb_Quantity.CssClass = "textbox1";
tc2.Controls.Add(tb_Quantity);
tr.Cells.Add(tc2);
TableCell tc3 = new TableCell();
Button btn_Delete = new Button();
btn_Delete.ID = "btn_Delete_" + sKey[1];
btn_Delete.CommandArgument = tr.ID;
btn_Delete.Click += new EventHandler(btn_DeleteTableRow_Click);
btn_Delete.Text = "Remove";
tc3.Controls.Add(btn_Delete);
tr.Cells.Add(tc3);
Table_Parts.Rows.Add(tr);
}
}
public void Reset()
{
Table_Parts.Controls.Clear();
RMAParts.Clear();
RowNumber = 0;
RMAParts.Add("PartRow_" + RowNumber.ToString(), new Part());
RowNumber = 1;
CreatePartRows();
}
protected void btn_AddPart_Click(object sender, EventArgs e)
{
RMAParts.Add("PartRow_" + RowNumber.ToString(), new Part());
RowNumber++;
}
protected void btn_DeleteTableRow_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
TableRow tr = (TableRow)Table_Parts.FindControl(btn.CommandArgument);
Table_Parts.Rows.Remove(tr);
RMAParts.Remove(btn.CommandArgument);
}
}