一見すると、私が確認することが2つあります。まず、実装していることを確認してくださいIPostBackDataHandler
。LoadPostData
これには、との 2 つのメソッドを実装する必要がありますRaisePostDataChangedEvent
。私の最初の推測では、最初のものはおそらくあなたの問題の原因です。
ポストバックを手動で処理する
LoadPostData
postDataKey
文字列と aを取り、ポストバックの結果として値が変更されたかどうかを示すaを返します。.Net が最初に意図した方法でこれを実装する必要はありません。たとえば、いくつかのラジオ ボタンを保持するコントロールを作成しました (ここでは重要ではないため、単にコントロールにすることはできません)。すべてプロパティによって名前が付けられ、そのために検査されました:NameValueCollection
postCollection
bool
RadioButtonList
string GroupName
postCollection
GroupName
public bool LoadPostData(string postDataKey,
System.Collections.Specialized.NameValueCollection postCollection)
{
bool oldValue = _isChecked;
postCollection = HttpContext.Current.Request.Form; // See note below
_isChecked = (postCollection[this.GroupName] == this.Text);
return oldValue == _isChecked;
}
postCollection
ここでを再定義していることに気付くでしょう。これは、コントロールが気にする必要があると ASP.Net が考えるものpostCollection
に対応する のサブセットのみが含まれているためです。HttpRequest.Form
ここで複合コントロールも作成しているので、おそらく同じことをしたいと思うでしょう。
これが最初にうまくいかなくても心配しないでください。デバッグ モードでこのメソッドに渡されたものをステップ実行して (または に出力するHttpContext.Trace
方が簡単なことがよくあります)、コードが必要なものではない理由を確認する価値があります。
簡単な警告
最後に 1 つ:LoadPostData
は、投稿されたフォームに、コントロールの と一致する名前のフィールドが含まれている場合にのみ呼び出されUniqueID
ます。コントロールは複合コントロールであるため、次のように、これを少しカウボーイしたい場合があります。
protected override void Render(HtmlTextWriter writer)
{
base.Render(writer);
writer.WriteBeginTag("input");
writer.WriteAttribute("type", "hidden");
writer.WriteAttribute("name", this.UniqueID);
writer.WriteAttribute("value", "post");
writer.Write(" />");
}
汚いハックですが、うまくいきます;o)
ビューステートを手動で処理する
ポストバックを手動で処理しても問題が解決しない場合は、コントロールのビューステートをいじる必要がある可能性があります。心配する必要はありません。いくつかの簡単なルールに従えば、見た目ほど怖くはありません。
ビューステートを手動で処理するには、明らかに と という 2 つのメソッドをオーバーライドする必要がありLoadViewState
ますSaveViewState
。1 つ目はビューステートの を受け取り、もう 1つは同じ構造object
を返します。object
永続化が必要なすべての重要なプロパティを保存するために必要な構造を含む何かをオーバーライドして返す場合は、メソッドSaveViewState
で再度インフレートするだけです。LoadViewState
ここで最初の狡猾なトリックが登場します。ビューステートの保存に使用する必要がある特定のデータ型があり、他の型は使用しないでください (他の型は非常に非効率的に格納されるため)。あなたにとっておそらく最も有用なタイプはSystem.Web.UI.Pair
、System.Web.UI.Triplet
と、古くからの友人であるSystem.Collections.ArrayList
とSystem.Collections.Hashtable
です。ペアとトリプレットは、 type の 2 つまたは 3 つの値を格納するだけobject
です。ArrayLists は事実上List<object>
.
あなたの状況では、おそらく(1)ラジオボタンの「チェック状態」を保存するブールフラグのArrayList、または(2)IDまたはインデックスを保存する文字列またはintのArrayListのいずれかを保存する必要があると思いますチェックされたラジオボタン。
前述のコントロールでは、checkedness とText
プロパティを格納するだけでよかったので、メソッドLoadViewState
とSaveViewState
メソッドは次のようになりました。
protected override void LoadViewState(object savedState)
{
Pair state = savedState as Pair;
if (state != null)
{
_isChecked = state.First as Nullable<bool> ?? false;
this.Text = state.Second as string;
}
}
protected override object SaveViewState()
{
return new Pair(_isChecked, this.Text);
}
繰り返しますが、これが初めてうまくいかない場合は、ほとんどの場合、コードをステップ実行するか、Trace に何かをスローする必要があります。重要なのは、viewstate が壊れているか、存在しないなどの場合に備えて、これらのメソッドから例外をスローしないようにすることです。
ビューステートの詳細情報
ビューステートをいじっているときに、ブックマークしておく非常に役立つ記事がいくつかあります。最初のものは、特定のタイプのみをビューステートに保存する必要がある理由 ( ArrayList
andHashtable
ではなくList<T>
andを使用するなどDictionary<TKey, TValue>
) について説明し、2 つ目は、これらすべてのビューステートが実際にどのように機能するかについての詳細な説明です。
- BinaryFormatter に手を出させないでください。
- ViewState を真に理解する
これがすべて問題の解決に役立つことを願っています。