1

以前、複数コントロールの単一ページ タイプのアプリケーションを動的にロードする開発を行っていたとき、viewstate に頭を悩ませていました。これは、後ではなく、 OnInitステージでコントロールを追加する必要があるためです。コントロール イベント (たとえば、ドロップダウン リストの selectedIndexChanged) を処理していたので、イベント ハンドラー ステージでそれらをロードしていました。子コントロール ページのサイクル キャッチアップについては知っていますが、うまくいかない場合があることに気付きました。

私は再びそのようなアプリケーションの開発を任されました。今回は別のアプローチを取ることにしました。値に基づいて動的コントロールをロードする選択コントロールについては、OnInit ステージで (Request.Form からの) ポストバック応答値をチェックし、すぐにコントロールをロードします。これは OnPreRender の直前であり、遅すぎるため、イベント ハンドラー ステージから動的コントロールをロードしません。

要約:
ページ サイクルの後半 (OnInit など) の早い段階で Request.Form コレクションからコントロールの値をチェックし、アクションを実行することの落とし穴は何ですか? ページ サイクルの後半で実際のコントロールからその値をチェックするのではなく?

4

1 に答える 1

0

落とし穴の 1 つは、コントロールが に含まれて<form>いない場合、存在しないことです。イベント ハンドラー ステージでそれらを追加することをお勧めします。これは、追加する内容がわかっているためです。ただし、これらのコントロールを再構築するために必要な情報は、ViewStateまたはSessionState

これを行うことでOnInit、 でそれらを再作成することができますが、現在進行中の道路を取り巻くその他の複雑さに対処する必要はありません。

それで、コントロールを構築する必要があることがわかったとしましょう。あなたはそれを構築します:

var tb = new TextBox();
tb.ID = "myTextBox";
...

ただし、必要な状態情報も保存します。

this.ViewState.StoreControl(typeof(TextBox), "myTextBox");

次に、拡張メソッドをビルドします。

public static void StoreControl(this StateBag vs, Type controlType, string name)
{
    var dynamicControls = vs["DynamicControls"] as List<Tuple<Type, string>>;
    if (dynamicControls == null)
    {
        dynamicControls = new List<Tuple<Type, string>>();
        vs["DynamicControls"] = dynamicControls;
    }

    var t = dynamicControls.FirstOrDefault(tp => tp.Item2 == name);
    if (t == null) { dynamicControls.Add(Tuple.Create(controlType, name)); }
}

次に、OnInit次のようなことを行う場合があります。

var dynamicControls = vs["DynamicControls"] as List<Tuple<Type, string>>;
if (dynamicControls != null)
{
    foreach (var tp in dynamicControls)
    {
        Control c = Activator.CreateInstance(tp.Item1) as Control;
        c.ID = tp.Item2;
        this.Controls.Add(c);
    }
}

注:このコードは SO で作成されました。コンパイルもデバッグもされていません。しかし、あなたはその考えを理解します。

于 2013-10-11T14:07:55.043 に答える