1

ASP.Net AJAX を使用して、ASP.Net 3.5 WebForms でカスタム コントロールを作成しています。コントロールに状態切り替えを作成しています (展開モードと折りたたみモード)。コントロールの現在の状態を ViewState に保持しようとしており、サーバー側のイベント ハンドラーで手動で変更しています。

object oExpanded = ViewState[ "Expandedness" ];
if(oExpanded == null)
{
    oExpanded = ListState.Collapsed;
}
ListState lsCurrentState = (ListState) oExpanded;
if(lsCurrentState == ListState.Collapsed)
{
    //code snipped - move to expanded mode here
    ViewState[ "Expandedness" ] = ListState.Expanded;
}
else
{
    //code snipped - move to collapsed mode here
    ViewState[ "Expandedness" ] = ListState.Collapsed;
}

重要ではないと思いますが、実際のレンダリングは updatepanel で行われ、上記のコードは非同期でトリガーされるイベント ハンドラーにあります。私が抱えている問題は、次のポストバックでViewState["Expandedness"]null が返されることです。Fritz Onion の Viewstate Decoder ツールを使用して、ポストバック間のビューステートの実際の内容を確認しようとしましたが、シリアル化されたデータが無効であることがわかりました。

ここで間違ったアプローチをしましたか?この問題に取り組む正しい方法は何ですか?

4

3 に答える 3

1

おっしゃる通り、UpdatePanel に入れても問題ありません。違いはありません。

コントロールまたはその親のいずれかでViewStateが無効になっていると思われます。親(ページまで)で無効になっている場合、コントロールでは無効になります。

これを回避するには、コントロールの代わりにページの ViewState ディクショナリを使用できます。

つまり、言う代わりに:

this.ViewState[ "Expandedness" ] = ListState.Expanded;

いう:

this.Page.ViewState[ "Expandedness" ] = ListState.Expanded;

ページ上にコントロールのインスタンスが複数存在する可能性がある場合は、次のように、ViewState キーが一意であることを確認する必要があります。

this.Page.ViewState[ this.ClientID + "Expandedness" ] = ListState.Expanded;

別の方法として (ViewState がページで無効になっている場合でも機能します)、Expandedness を ControlState に格納することを検討できます。少しトリッキーですが、Google で検索すると、コード サンプルがすぐに見つかります。ControlState には最小限の情報のみを格納することをお勧めしますが、このような 1 つのフラグでも問題ありません (実際には、このフラグが設計されている目的です)。

于 2009-02-24T23:01:13.260 に答える
0

詳細な調査: サブコントロール イベント ハンドラーで行った Viewstate への変更は、Page_Prerender (つまり、ページのイベント ライフサイクルの後半) まで続くため、問題は Viewstate が書き込まれないことではありません。ただし、ページへの後続のポストバック (同期または非同期) では、viewstate にその値が表示されません。

于 2009-02-24T23:01:07.100 に答える
0

いつこのコードを呼び出しますか? Page_Init で呼び出された場合は早すぎて、viewstate に加えた変更は無視されます。

ちょっとした考え

于 2009-02-24T22:41:39.173 に答える