2015年6月6日土曜日

[ASP.NET] 動的に追加したイベントが動作しない

How to keep additional events after PostBack
ASP.NETでユーザーの操作によって画面にボタンを追加するアプリを作ったときに悩んだ内容をまとめました。
ボタンをクリックしたら新しいボタンを画面に追加するアプリを作ったのですが、新しいボタンのイベントが実行されません。


環境

・Windows8.1
・Visual Studio Community 2013
・C#


イベントが動作しない例

1. Button1をクリックすると新しいボタンを追加する
2. 新しいボタンをクリックするとラベルの文字を変化させる
というWebアプリを作ろうとして失敗した例です。

DynamicControls.aspx


DynamicControls.aspx.cs


DynamicControls.aspx.designer.cs


実行するとこうなります。
Button1をクリックすると新しいボタンが追加されるまではいいのですが
新しいボタンをクリックしても期待通りに動作しません。


修正後

[HOWTO] Visual C# .NET を使用して ASP.NET で動的にコントロールを作成する方法
http://support.microsoft.com/kb/317794/ja
によると
OnInit イベント ハンドラまたは Page_Load イベント ハンドラで、作成したコントロールをコントロール コレクションに追加する必要があります。
とのことです。

上のソースで期待通りに操作しなかった原因は、動的に追加するボタンをOnInitイベントやPage_Loadイベントで追加しなかったためです。

新しいボタンを追加する処理をPage_Loadイベントで発生させるように修正します。
ただし、ASP.NETはイベントごとにポストバックが発生し、OnInitイベントやPage_Loadイベントが処理されます。
Button1をクリックしたときだけPage_Loadで新しいボタンを追加するように工夫します。

ボタンのUseSubmitBehaviorプロパティをFalseに設定すると、ポストバックした際Page_LoadイベントのRequest["__EVENTTARGET"]にボスとバックさせたボタンのIDが設定されます。

というわけで
・ボタンの追加をPage_Loadイベントで処理
・ボタンのUseSubmitBehaviorをFalseに設定
に修正したのが次のソースです。


これで期待通りに動作しました。


まとめ

動的に追加したイベントはポストバック後のPage_Loadより後に発生します。
動的にコントロールを追加する場合はポストバックの前と後に画面に配置するように工夫すればすればいいと思います。

※ボタンを配置して生成されるHTMLタグはUseSubmitBehaviorプロパティが
Trueの場合は<input type="submit">
Falseの場合は<input type="button"> とonclickイベントのJavaScript
に変わります。プロパティ名通り振る舞いが変わるのでリファクタリングするときは要注意です。



関連ブログ

[ASP.NET] ポストバック処理で実行するJavaScriptを選ぶ方法
[ASP.NET] 動的に追加したラベルやテキストボックスが消える現象の対策
[C#] タスクトレイにバルーンチップを表示するアプリ
[Unity3D] Visual Studio Community 2013を日本語化してUnityアプリを作る
Unity3DのソースをVisual Studio Expressで編集する

以上、参考になれば幸いです。

0 件のコメント:

コメントを投稿