Extender で拡張されたカスタムコントロールを作成する。

AJAX Control Toolkit の使用について(@IT Insider.NET 会議室) より
TextBox を FilterdTextBoxExtender で拡張したカスタムコントロールを作成したいとのこと。

#2007/11/09 --------------
このままだとうまくいかないみたい。
Button Click などのタイミングで動的にコントロールを追加する分にはいいけれど、デザイナでカスタムコントロールをドロップすると Extender の初期化でおこられる。
継承元を Container な Control にして TextBox と Extender をメンバに持つようにしたほうがいいかな。
#2007/11/09 --------------

#2007/11/14 --------------
こっちでちょっと考えてみた。
http://d.hatena.ne.jp/karuakun/20071114
#2007/11/14 --------------


提示されたコードを見ると Renderメソッド を Override して Extender を Control に関連付けている。
このままだと TextBox は表示されるけれど Extender のコードが Page に書き出されない。
提示されたコード


Public Class BaseFieldNumber
Inherits System.Web.UI.WebControls.TextBox
Private cFilteredTextBoxExtender As AjaxControlToolkit.FilteredTextBoxExtender
Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
cFilteredTextBoxExtender = New AjaxControlToolkit.FilteredTextBoxExtender
cFilteredTextBoxExtender.TargetControlID = Me.ID
cFilteredTextBoxExtender.FilterType = AjaxControlToolkit.FilterTypes.Numbers
MyBase.Render(writer)
End Sub
End Class

コンパイルは通るけれど、吐き出された HTML を見てみると Sys.Applciation.add_init では Extender が追加されていない。


<script type="text/javascript">
<!--
Sys.Application.initialize();
Sys.Application.add_init(function() {
});
// -->
</script>

Extender を作って Control に関連付けるのはいいんだけれど、Container に追加していないのでそのまま捨てられているっぽいですね。
Render で コントロールに Extender を追加すると InvalidOperationException が発生する。
Extender controls may not be registered after PreRender とのことなので、Render だと遅すぎるってことですね。
コントロールの設定という意味ではコントロールの内容を書き出す Render ではなくて、 Init なりで設定を行う必要がある。


Public Class BaseFieldNumber
Inherits System.Web.UI.WebControls.TextBox

Private cFilteredTextBoxExtender As AjaxControlToolkit.FilteredTextBoxExtender

Private Sub BaseFieldNumber_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
cFilteredTextBoxExtender = New AjaxControlToolkit.FilteredTextBoxExtender
cFilteredTextBoxExtender.TargetControlID = Me.ID
cFilteredTextBoxExtender.FilterType = AjaxControlToolkit.FilterTypes.Numbers
Me.Parent.Controls.Add(cFilteredTextBoxExtender)
End Sub
End Class

最初 カスタムコントロールに追加した Extender を ScriptManager がちゃんと理解してくれるか不安だったんだけれど、吐き出された HTML を見ると Script がロードされ関連付けがされている。


<script type="text/javascript">
<!--
Sys.Application.initialize();
Sys.Application.add_init(function() {
$create(AjaxControlToolkit.FilteredTextBoxBehavior, {"FilterType":2,"id":"ctl02"}, null, null, $get("NumberField1"));
});
// -->
</script>