5

動的に作成されたコントロールをホストするカスタムUserControlを使用していますが、ViewState情報が失われているように見える奇妙な状況に遭遇しています。base.SaveViewState()呼び出しでオーバーライドされたSaveViewStateメソッドでは、ViewStateにあったすべてのものを含むオブジェクトが返されると期待しますが、代わりにnullを返します。

protected override object SaveViewState()
{

    object[] tempState = new object[2];
    tempState[0] = base.SaveViewState(); //***suspected issue here, tempState[0] == null -- why?
    //? this.ViewState["CompanyID"] returns me the guid I'm expecting
    //... code instantiating and populating lstDataControlInfos
    tempState[1] = lstDataControlInfos;
    return tempState;
}

そのメソッドにブレークポイントを設定し、イミディエイトウィンドウを使用してViewState ["CompanyID"]をクエリし、ViewStateに実際にCompanyIDが格納されていることを確認できます。たぶん私はViewStateについて何か誤解していますが、その呼び出しはすでにViewStateにあるもの(私のCompanyIDを含む)を返すべきではありませんか?この問題は、オーバーライドされたLoadViewStateメソッドのポストバックで問題になります。これは、CompanyIDをViewStateから取得する方法がなくなったためです。nullに戻ります。

protected override void LoadViewState(object savedState)
{
    object[] tempState = (object[])savedState;
    //tempState[0] == null, as it was stored in the previous SaveViewState call
    //any reference to ViewState["CompanyID"] comes back null
    base.LoadViewState(tempState[0]);
}

このコントロール内にViewStateにシリアル化および逆シリアル化する動的コントロールがあると述べましたが、それらはすべて正しく機能しているようです。ファクトを知っていて、SaveViewState呼び出し中にViewStateにデータがあることを(即時ウィンドウを介して)確認できる場合、base.SaveViewState()がnullを返す原因は何ですか?

4

1 に答える 1

3

値をViewStateに保存すると、ViewStateが追跡されている場合、値はダーティとしてマークされます。

追跡はTrackViewStateで開始されます。これは、Initializeの後、Loadの前です。

追跡は、PreRenderの後のSaveViewStateで終了します。

ViewStateに値が設定されているときにViewStateが追跡されていない場合、SaveViewStateを呼び出したときにその値は保持されません。これは良いことです。つまり、シリアル化されたViewStateを肥大化させることなく、初期化フェーズでViewStateを使用できるということです。

ツリーにコントロールを動的に追加する場合は、次の点に注意してください。

  • コントロールツリーにコントロールを追加する前に設定された値は、ViewStateの追跡中にコントロールを追加しても保持されません。

  • ViewStateが追跡されているフェーズにいる場合、コントロールをコントロールツリーに追加した設定された値は保持されます。

ページライフサイクルのどの時点でViewState["CompanyID"]を設定していますか。また、コントロールをコントロールツリーに追加する前または後に設定していますか。

于 2012-10-23T20:31:05.430 に答える