ASP.NET のカスタムサーバーコントロールで PostBack を処理する
SPECIAL
カスタムサーバーコントロールの PostBack
カスタムサーバーコントロールを Visual Studio .NET 2008 SP1 で作成した場合、"WebControl" から派生したカスタムサーバーコントロールは、ポストバック時に値が復元されないようです。
ポストバック時に入力情報を復元するためには、"System.Web.UI.IPostBackDataHandler" インターフェイスを実装して、ポストバック時の復元コードを記載する必要がありました。
IPostBackDataHandler インターフェイスを継承する
まず、"IPostBackDataHandler" インターフェイスを、当該カスタムサーバーコントロールで継承します。
"IPostBackDataHandler" インターフェイスで定義されている "LoadPostData" メソッド及び "RaisePostDataChangedEvent" メソッドの定義を実装します。また、"WebControl" の "OnLoad" メソッドをオーバーライドして、"Page.RegisterRequiresPostBack" メソッドを使用して、自身をポストバック時に処理が必要なオブジェクトとして登録しておく必要があります。
[DefaultProperty("Text")]
[ToolboxData("<{0}:SampleControl runat=server></{0}:SampleControl>")]
public class SampleControl : WebControl, IPostBackDataHandler
{
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
// 自身をポストバック処理の対象として登録します。
Page.RegisterRequiresPostBack(this);
}
// ポストバック情報を読み込む際にロードされます。
public virtual bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection values)
{
}
// RaisePostDataChangedEvent が発生した際に実行されます。
public virtual void RaisePostDataChangedEvent()
{
}
}
"Page.RegisterRequiresPostBack" メソッドの実行を忘れると、ポストバック時に "LoadPostData" が呼び出されないので注意しましょう。
PostBack 時に値を復元する
ポストバックされた際に元の値を復元する処理は、"LoadPostData" メソッド内に実装します。
public virtual bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection values)
{
string postdata = values[postDataKey];
if (postdata != null)
{
DataText = postdata;
}
return false;
}
ポストバック時には、"values" 引数にポストバックされた値が設定された状態で、自動的に "LoadPostData" が呼び出されます。
"postDataKey" 引数には、自身の ID が渡されますので、その値を編集フィールドの ID として HTML 出力している場合には、"values[postDataKey]" とすることで、ポストバックされた値を取得することが可能です。値がポストバックされていない場合には Null が取得されます。
入力フィールドが複数存在する場合や、HTML で別の ID 名を設定してある場合には、その名称を指定してポストバックの値を取得します。例えば "sample_id" という名前が設定されているフィールド値ならば "values["sample_id"]" という形で取得できます。なお、HTML に出力する ID は、"ID" 属性の他、"name" 属性でも大丈夫のようでした。
"LoadPostData" メソッドが返す引数ですが、これを True にした場合、"RaisePostDataChangedEvent" が実行されるようです。
ポストバックの結果、サーバーコントロールの状態が変化する場合は True を指定するとのことです。詳しい事は分らないのですが、サーバーコントロールには "コントロールの状態 (ControlState)" という状態情報を保持する機能があるようですので、それと何か関係しているのかもしれません。
とりあえず、ここで false を指定しても、ViewState[] に設定した値は画面に反映される様子です。