概要
ASP.net Webフォームで、コントローラのHTMLを動的に生成、追加し、イベントハンドラを紐付ける(正確には紐付いてはいませんが。。。)方法について説明します。
今回はbuttonコントローラ(buttonタグ)を動的に追加する方法を例として紹介します。
前提環境
- Windows 10
- Visual Studio Professional 2019
- .NET Framework 4.2
- C#
コードのポイント
- 「Page.Form.Controls.Add(button);」で動的にコントローラを追加できるのですが、この方法では任意の場所や、動的に作成しているHTML内に設定することができません。
- コントロールのHTML化(HTMLの生成)は、RenderControlメソッドを使用しますが、StringWriterを使うのがポイントです。
- 動的に生成し、かつControls.Addを使用しない場合、イベントハンドラと紐付けられません。そのため、どのボタンが押下されたのかをRequest[“__EVENTTARGET”]を使って判定して、イベント用のメソッドを呼び出します。
サンプルコード
protected void Page_Load(object sender, EventArgs e)
{
// 出力用のWriterの準備。StringWriterを用意するのがポイント。
StringBuilder builder = new StringBuilder();
StringWriter writer = new StringWriter(builder);
HtmlTextWriter htmlWriter = new HtmlTextWriter(writer);
// ボタンコントロールの作成
Button btn = new Button();
btn.Text = "新規ボタン";
btn.ID = "newButton"; // ボタンを複数設置するときはIDが重複しないように!
// JavaScript用のScriptである「__doPost」を作成する。
string script = Page.ClientScript.GetPostBackEventReference(btn, string.Empty);
btn.OnClientClick = script;
btn.UseSubmitBehavior = false; // trueだと「__doPost」がHTMLに反映されない。
btn.RenderControl(htmlWriter);
// HtmlWriterに出力
// innerAreaはデザイナ上で追加した「<div id="innerArea" runat="server">」タグのID
// Writerの大元であるStringBuilderでHTMLの文字列出力
innerArea.InnerHtml += builder.ToString();
// ..中略..
if (isPostBack) {
// イベントが発生しないので対象ボタンを確認してメソッドを呼び出す。
// 通常のイベントはPage_Loadが終わってから呼び出されるが、
// これはPage_Loadの実行中であるため、Page_Loadの最後に記載する
string eventTarget = (string)Request["__EVENTTARGET"];
if (! String.IsNullOrEmpty(eventTarget) && eventTarget == "newButton")
{
// 別途用意したイベントハンドラ用のメソッドを呼び出す。
Btn_Click(sender, e);
}
}
// イベントハンドラ用に用意しているメソッド
protected void Btn_Click(object sender, EventArgs e)
{
// ..省略..