11

asp.netに頭を包み込もうとしています。私は長年のphp開発者としての経歴を持っていますが、現在asp.netを学習するという課題に直面しており、問題を抱えています。フレームワークを意図しないものに強制しようとしているためかもしれません。そのため、「正しい方法」でそれを行う方法を学びたいと思います。:-)

私の問題は、実行時にプログラムでページにコントロールを追加する方法です。私が理解できる限り、次のPostBackでコントロールが消えるので、page_initでコントロールを作成する必要があります。しかし、以前のPostBackの値に依存しているため、page_initに追加するコントロールがわからないという問題に何度も直面しています。

単純なシナリオは、デザイナーにドロップダウンコントロールが追加されたフォームです。ドロップダウンはAutoPostBackに設定されています。PostBackが発生した場合、ドロップダウンコントロールから選択した値に依存する1つ以上のコントロールをレンダリングする必要があり、できればそれらのコントロールをデザインによって追加されたかのように動作させる必要があります(「ポストバックされたときの動作」のように)。

私はここで間違った道を進んでいますか?

4

9 に答える 9

9

ここで行われた他のポイント「コントロールを動的に作成することから抜け出せる場合は、そうしてください...」(@ Jesper Blad Jenson akaによる) に同意しますが、これは私が過去に動的に作成されたコントロールで解決したトリックです。

問題は鶏と卵になります。コントロール ツリーを作成するには ViewState が必要であり、ViewState を取得するにはコントロール ツリーを作成する必要があります。まあ、それはほぼ正しいです。ツリーの残りの部分が読み込まれる直前に、 ViewState の値を取得する方法があります。LoadViewState(...)それは、 andをオーバーライドすることSaveViewState(...)です。

SaveViewState に、作成するコントロールを保存します。

protected override object SaveViewState()
{
    object[] myState = new object[2];
    myState[0] = base.SaveViewState();
    myState[1] = controlPickerDropDown.SelectedValue;

    return myState
}

フレームワークが「LoadViewState」オーバーライドを呼び出すと、「SaveViewState」から返された正確なオブジェクトが返されます。

protected override void LoadViewState(object savedState) 
{
    object[] myState = (object[])savedState;

    // Here is the trick, use the value you saved here to create your control tree.
    CreateControlBasedOnDropDownValue(myState[1]);

    // Call the base method to ensure everything works correctly.
    base.LoadViewState(myState[0]);
}

これを使用して、DataSet が ViewState にシリアル化された ASP.Net ページを作成して、データのグリッド全体に変更を保存し、ユーザーが PostBacks を使用して複数の編集を行い、最終的にすべての変更を単一の「保存」でコミ​​ットできるようにしました。手術。

于 2008-09-22T06:55:57.387 に答える
3

OnInit イベント内にコントロールを追加する必要があり、viewstate は保持されます。if(ispostback) は使用しないでください。コントロールはポストバックのイベントごとに追加する必要があるためです。
ビューステートの (De) シリアル化は、OnInit の後、OnLoad の前に発生するため、ビューステート永続化プロバイダーは、OnInit に追加された場合、動的に追加されたコントロールを認識します。

しかし、あなたが説明しているシナリオでは、おそらくマルチビューまたは単純な非表示/表示 (可視プロパティ) がより良い解決策になるでしょう。
これは、OnInit イベントで、ドロップダウンを読み取って新しいコントロールを追加する必要があるときに、viewstate がまだ読み取られておらず (デシリアライズされていない)、ユーザーが何を選択したかがわからないためです。( request.form() を実行できますが、それはちょっと間違っているように感じます)

于 2008-09-22T06:23:52.067 に答える
2

しばらくの間この問題に取り組んだ後、うまくいくように見えるこれらの基本ルールを思いつきましたが、YMMV.

  • 可能な限り宣言型コントロールを使用する
  • 可能であればデータバインディングを使用する
  • ViewState の仕組みを理解する
  • Visibilty プロパティは長い道のりを歩むことができます
  • イベント ハンドラーで追加コントロールを使用する必要がある場合は、Aydsman のヒントを使用して、オーバーライドされた LoadViewState でコントロールを再作成します。

本当にViewStateを理解することは必読です。

例による動的コントロールの理解では、動的コントロールの代わりにデータバインディングを使用する方法についていくつかのテクニックを示します。

動的制御を真に理解することで、動的制御を回避するために使用できる手法も明確になります。

これが同じ問題を抱えている他の人に役立つことを願っています。

于 2008-09-30T08:07:14.440 に答える
1

本当に動的コントロールを使用する必要がある場合は、次のようにする必要があります。

  • OnInit で、前の要求が満たされたときにページにあったものとまったく同じコントロール階層を再作成します。(もちろん、これが最初の要求でない場合)
  • OnInit の後、フレームワークは前のリクエストからビューステートをロードし、すべてのコントロールが安定した状態になるはずです。
  • OnLoad で、不要なコントロールを削除し、必要なものを追加します。また、次のリクエストの最初のステップで使用するために、この時点で現在のコントロール ツリーを何らかの方法で保存する必要があります。動的コントロール ツリーの作成方法を指示するセッション変数を使用できます。Controls コレクション全体を一度セッションに保存したことさえあります (ピッチフォークは脇に置いておいてください。これは単なるデモ用でした)。

とにかく必要がなく、OnLoad で削除される「古い」コントロールを再度追加することは少し奇妙に思えますが、Asp.Net は実際には動的なコントロールの作成を念頭に置いて設計されていません。ビューステートの読み込み中にまったく同じコントロール階層が保持されない場合、古いコントロールの状態が新しく追加されたコントロールに読み込まれるため、見つけにくいあらゆる種類のバグがページに潜み始めます。

Asp.Net ページのライフ サイクル、特にビューステートがどのように機能するかをよく読んでください。

編集: これは、viewstate の動作と、動的コントロールを扱う際に考慮すべきことについての非常に良い記事です: http://geekswithblogs.net/FrostRed/archive/2007/02/17/106547.aspx

于 2008-09-22T06:46:46.753 に答える
0

唯一の正解はAydsmanによって与えられました。LoadViewStateは、動的コントロールを追加する唯一の場所であり、再作成時にビューステート値が復元され、追加するコントロールを決定するためにビューステートにアクセスできます。

于 2008-09-23T15:08:10.317 に答える
0

上手。コントロールの動的な作成から抜け出すことができる場合は、そうします。それ以外の場合は、Page_Initの代わりにPage_Loadを使用しますが、If Not IsPostBack内に何かを配置する代わりに、メソッドに直接iを設定します。

于 2008-09-22T06:12:55.447 に答える
0

ここでの答えはコントロールにあると思います。MultiViewたとえば、ドロップダウンはマルチビューの異なるビューを切り替えます。

マルチビューの現在のビュープロパティをドロップダウンの値にデータバインドすることもできます。

于 2008-09-22T06:13:00.987 に答える
0

ああ、それはASP.NETWebフォームのリークのある抽象化の問題です。

このstackoverflow.comWebサイトの作成に使用されたASP.NETMVCに興味があるかもしれません。これは、PHP(つまり、HTMLとJavascriptに関しては、ペダルを踏む)のバックグラウンドから来ているので、あなたにとってより簡単なはずです。

于 2008-09-22T06:13:48.457 に答える
0

これは、「C# 2008 での Pro ASP.NET 3.5」という本で、動的コントロールの作成のセクションで出くわしました。

コントロールを複数回再作成する必要がある場合は、Page.Load イベント ハンドラーでコントロールの作成を実行する必要があります。これには、動的コントロールでビュー ステートを使用できるという追加の利点があります。通常、ビュー ステートは Page.Load イベントの前に復元されますが、Page.Load イベントのハンドラーでコントロールを作成すると、ASP.NET は、Page.Load イベント ハンドラーの終了後に保持されているビュー ステート情報を適用します。このプロセスは自動的に行われます。

私はこれをテストしていませんが、調べてみてください。

于 2008-09-23T22:43:11.300 に答える