ASP.NET2.0にてjavascriptによる連携DropDownList

PostBackなしに、2つのDropDownListを連携させる(ddl1の選択値によりddl2の内容を動的に構築する)際の、備忘録をば。
以下はjavascriptのサンプル。

var list = new Array("0", "0,1,2", "0,1");
function SetDdl2Items(){
var se11 = document.getElementById("ddl1");
var sel2 = document.getElementById("ddl2");
var ops = new Array(
new Option("値1","1"),
new Option("値2","2"),
new Option("値3","3"));
var indexes = list[sel1.selectedIndex].split(",");
while(sel2.options.length > 0){
sel2.options.remove(0);
}
for(var i=0; i

Arrayを組み立てる辺りと、listを組み立てる辺りをサーバーサイドで作り、ClientScript登録する。初期表示にも対応するが、javascriptで内容を構成したddl2は、サーバーコントロールを使っていてもchange系イベントを捕捉することや、selectedValue、selectedIndexを取得することは適わないようだ(暫定回避策は後述)。
加えて、ViewState解釈のセキュリティチェックの兼ね合いか、submit等によるPostBackが発生した際、内容再構成ができずに、「無効なポストバックまたはコールバック引数です。」のようなエラーとなる。これについては、Renderをoverrideし、ClientScript.RegisterForEventValidationで回避可能。
(<%@ Page EnableEventValidation="false" %> を記述する手もあるが、どうみてもこれは実践ではやりたくない。http://msdn.microsoft.com/ja-jp/library/system.web.ui.page.enableeventvalidation.aspx

PageのRenderイベントハンドラにて
ClientScript.RegisterForEventValidation(ddl1.UniqueID, "値1");
ClientScript.RegisterForEventValidation(ddl1.UniqueID, "値2");
...
(↑実際は当然、ループで)

また、これ以外にも、DDLカスタムコントロールを作成し、以下の処理を加えることで回避可能。

protected override bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
{
string value = postCollection.GetValues(postDataKey)[0];

if (value == null && this.Items.FindByValue(value) == null)
{
this.Items.Add(value);
}
return base.LoadPostData(postDataKey, postCollection);
}

更に、submit時にselectedValue等を取りたい場合(検索条件として使う場合とか)、少々強引ではあるが、あらかじめ、通常のサーバーコントロールDDLを使うが如く、初回にItemをBindしておけば、サーバーコントロールとしての面目も保たれるようで、javascriptによる動的内容構成を行っても、selectedValueが利くようになる。これについては、もっと正しいやり方があろう。
ひとまず、これにて。