7

これが私の問題です。ユーザーがボタンクリックを使用して必要な数のインスタンスを追加できるようにするユーザーコントロールがあります(ボタンがクリックされるたびに、ユーザーコントロールの別のインスタンスをパネルに追加したい)。最初は問題なく動作しますが、追加のポストバックごとに、追加されたすべてのコントロールが削除されます。ユーザーが追加したユーザー コントロールの数を追跡するのに問題はありませんが、ポストバック前と同じ状態を維持するにはどうすればよいですか? SaveViewState と LoadViewState を使用している人々に関する投稿をいくつか読みましたが、例を見つけることができませんでした。

私の最大の問題は、各ユーザー コントロールのすべてのテキスト ボックスとドロップダウン リストに、各ポスト バック後に同じテキスト/選択した値/データが入力されたままになるようにすることです。

前もって感謝します、ベン

4

7 に答える 7

10

プログラムでページにコントロールを追加しているため、ポストバックごとに再作成する必要があります。

また、プログラムで追加されたコントロールPreInitまたはInitページのイベントを再作成する必要があります。これは、イベント管理を復元する適切なビューステートのためです。

これを行わないと、ポストバックで制御が失われ、イベントが処理されなくなります。

編集

に動的コントロールを追加することをお勧めしますが、PreInit( InitDustin Hodges が言うように) に追加すると機能する可能性があることは事実ですpage_load。他に選択肢がない限り、避けるべきだと思います。

コントロールを Page_Load イベント ハンドラーにロードし、ビュー ステートを適切に維持することで問題を解決できる場合があります。
それはすべて、動的に読み込まれたコントロールのプロパティをプログラムで設定しているかどうかに依存します。設定している場合は、Controls.Add(dynamicControl) 行に対して相対的に設定している場合です。
これについての詳細な説明は、この記事の範囲を少し超えていますが、それが機能する理由は、Controls プロパティの Add() メソッドが、ビュー ステートの読み込み段階を過ぎても、親のビュー ステートをその子に再帰的に読み込むためです。

ソースMSDN

于 2010-10-15T19:21:29.150 に答える
4

これはあなたを助けるでしょう

http://www.codeasp.net/blogs/SumitArora/microsoft-net/841/value-of-dynamic-textbox-lost-on-postback

あなたもこれを読んで

http://www.codeasp.net/blogs/Vinz/microsoft-net/256/links-to-read-before-working-on-dynamic-controls-in-asp-net

ありがとう

かのように

于 2010-10-16T12:52:40.690 に答える
2

ユーザーが追加したコントロールの数を追跡している場合は、ユーザーが以前に追加したコントロールを、できればPage_InitまたはPage_Loadで再作成する必要があります。そのハンドラーに次のようなものを追加します。

for(int i=0; i<NumberOfControlsUserHasAdded; i++)
{
    //todo:  change this to the appropriate user control
    TextBox tb = new TextBox();
    tb.ID = "tb" + i.ToString();
    //todo:  add to appropriate control collection
    this.Controls.Add(tb);
}

この方法で行う場合は、コントロールの状態を維持する必要があります。これは、tbコントロールをコントロールコレクションに追加すると、イベントに追いつき、自動的にビューステートを復元する必要があるためです。

ほとんどの場合、ビューステートに保存されるため、セッション中の状態を追跡する必要はありません。

于 2010-10-15T19:24:29.917 に答える
1

古いプロジェクトでこれをやり遂げようとしたとき、私は悪夢に見舞われました。途中で、自分が思っていたよりも Web 開発についての知識が少ないことに気付きました (この Web サイトを読むことは、1 時間ごとではないにしても、毎日自分を謙虚にするための優れた方法です)。そのプロジェクトでは、コントロールを動的にインスタンス化していたので、Page.IsPostBack はまったく役に立ちませんでした。

そうは言っても、私が提案できる最善のことは、セッション変数の使用を検討することです。ページから取得したデータを表すクラス (またはクラスのコレクション) がある場合、コードの読みやすさを向上させるためにそのクラス/コレクションに値を格納し、それをセッション。

于 2010-10-15T19:19:54.457 に答える
0

大量のユーザーがいる場合は醜い解決策ですが、ユーザーコントロール自体をセッションに固定することもできます。フッターを再作成するためにページが変更されるたびにデータベースをヒットしたくないので、フッターコントロールを使用してこれを行います。

このソリューションは、ユーザーが多く、この機能を頻繁に使用している場合、サーバー上で実際にタスクを実行する可能性があります。少なくとも私はそうなると思います...

ただし、page_loadにユーザーコントロールが含まれているプレースホルダーを再設定することもできます。すぐに例をあげることができます。

私がしていることの例:

if (Session["footer"] == null)
{
 Session["footer"] = new Footer(LinksRules.BuildFooterLinks((int)WebSiteSections.Main));// where Footer is my control
}
footerPH.Controls.Add((Footer)Session["footer"]);

シングルトンパターンのようなもの...

だから私が見るように、あなたはポストバックを引き起こすものなら何でもこれをすることができます

Session ["DynamicControls"] = PlaceHolder.Controls;

そして、ページロードメソッドでは、次のことができます。

foreach(var control in (List<Controls>)Session["DynamicControls"])
{
  yourPlaceHolder.Controls.Add(control);
}

セッションオブジェクトがnullの場合は、これまでにないようなオブジェクトを1つ追加するだけです。

私はこれがあなたが望むようにコントロール内のデータに固執すると信じています。

于 2010-10-15T19:25:21.887 に答える
0

あなたを見て、パネルをクリアする行の前にPageLoad追加します。if(!this.IsPostBack)

これはもちろん推測にすぎませんが、問題がこれに関連しているという多くの質問を見てきました

于 2010-10-15T19:16:46.893 に答える
0

ボタンをクリックして追加すると、Page_Load新しいページが作成されます。次に、ボタン クリック メソッドによってコントロールが追加され、ページのレンダリングが終了します。2 回目にクリックするPage_Loadと、ページが作成され、ボタン クリック メソッドが再びコントロールを作成してページに追加します。残念ながら、以前に追加したものはもうありません。

コントロールを Repeater に追加するとどうなるでしょうか? Repeater のビュー ステートは、追加した各コントロールを追跡して、ポストバック時に吹き飛ばされないようにすることができます。

于 2010-10-15T19:17:36.547 に答える