- - PR -
動的に生成したTextBoxの値に関して
1
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2004-12-18 11:10
こんにちは。Keiと申します。
現在 VisualStudio2003/vb.net でWebアプリを開発しております。 現在とても困っていることがありまして、どなたかお力を貸して頂けませんでしょうか? 1. 動的にテキストボックスを作成する。(Page_Loadイベント時) 2. PostBackした時に同様にテキストボックスを作成し、値のみ書き換える。 上記を行いたいのですが、デバッグ時には正しく動作(書き換えた値がテキストボックスへ挿入される)するのですが、画面には反映されません。。。 この問題は.netの仕様だそうですが、どなたか回避方法をご存知ないでしょうか? どうかよろしくお願いします。。。 | ||||||||
|
投稿日時: 2004-12-18 12:08
デバッグ時には正しく動作しているなら、リリース時とデバッグ時の違いに問題があるのであって、.NET Frameworkの仕様は関係ないのでは?
_________________ | ||||||||
|
投稿日時: 2004-12-18 12:20
Jitta様 ご返信ありがとうございます。
私の説明が足りなくて申し訳ありません。。。 現在下記問題を回避したいのです。 http://support.microsoft.com/default.aspx?scid=kb;ja;316813 Page_Load時にテキストボックスの値を書き換えているのですが、画面が生成された時点で、 PostBack前の値にまた書き換えられているようなのです。 回避方法ご存知ないでしょうか? | ||||||||
|
投稿日時: 2004-12-18 14:59
いままで気づきませんでした・・ 2で新しくTextBoxを作成したときに TextBox.ID = "適当なID"; //つまり1で作成したときと異なるIDにする と、してみてはどうでしょうか?(IDを変えることが仕様的に可能なら)
デバックビルドでもブラウザには表示されないのですよね? | ||||||||
|
投稿日時: 2004-12-18 14:59
もう少し具体的に問題を示していただけるとありがたいんですが。
差し支えない範囲のソースとか。 | ||||||||
|
投稿日時: 2004-12-18 16:46
Page_PreRenderにて値をセットすれば、とりあえず一つの回避策となるかもしれません。
スレ主に代わって再現コードです。 ------------------------------- EnableViewState="False" ------------------------------- Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim TextBox1 As TextBox = New TextBox() With TextBox1 .ID = "TextBox1" If Not Me.IsPostBack Then .Text = "First" Else .Text = "PostBack" End If Me.Panel1.Controls.Add(TextBox1) End With End Sub 'Private Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.PreRender ' If Me.IsPostBack Then ' CType(Me.Panel1.FindControl("TextBox1"), TextBox).Text = "PostBack2" ' End If 'End Sub ------------------------------- # RaisePostBackEvent メソッドより前でText値が書き変わってる!? [追記]ソースの一部を削除 [ メッセージ編集済み 編集者: えんぞ@見習 編集日時 2004-12-18 16:48 ] | ||||||||
|
投稿日時: 2004-12-21 21:43
Loadイベントハンドラで作成するのはやめましょう。生成はページの初期化処理イベントハンドラであるPage_initで行いましょう。 Visual C# .NET を使用して ASP.NET で動的にコントロールを作成する方法 で、「[PRB] EnableViewState が False に設定されていてもサーバー コントロールの状態が維持される」は、「ViewStateをfalseにしても、内容が保持される」であって、プログラム内の変更が反映されない、というのとはちょっと違いますよね。つまり、 1.CheckBoxのSaveViewStateをFalseにする 2.Not IsPostBack で、CheckBoxコントロールの背景色を Tomato にする 3.クライアントで Tomato で表示される 4.クライアントで「チェック」する 5.クライアントでPostする 6.サーバで処理される 7.再読込後、背景色は保持されていない、がチェックはされたまま という現象が発生し、「PostBack前後で保持されないはずのデータ(チェック状態)が保持された」と。おそらく、kei69さんの内容は、SaveViewStateの設定に関係なく発生すると思います。 それで、1年半以上前のことなので少々不安ですが、私の経験では、Loadイベントハンドラで追加したコントロールに対しては、PostBackによるイベントが発生しなかったと思うのです。「コントロール実行の有効期間」というトピックに、イベントやコールされるメソッドの順番が書かれていますが、InitイベントはLoadViewStateやLoadPostDataよりも前に発生します。Loadイベントはその後に発生します。LoadイベントではPostDataの読み込みがすんでいますから、ここで値を変えると、ユーザが変更した値を上書きで変更したことになり、イベントがキャンセルされたように思います。 もちろん、WindowsアプリケーションではChangedイベントはプログラム中から変更しても発生します。ただし、ここで問題になるのは、“Changedイベントが発生する要因”です。 Changedイベントは、ある値が別の値に変更されるから発生します。では、ページ要求ごとに新しいオブジェクトを作成するWebアプリケーションにとって、“変更前の値”とはなんでしょう?これがViewStateにある、“送信前の値”になります。では、“送信前の値”と、“受信した値”が違っているというのを、どこで判断するのでしょう?Windowsアプリケーションでは、セットアクセサの先頭または最後にOn〜Changeメソッドの呼び出しがコーディングされているようです。WebアプリケーションではIPostBackDataHandler.LoadPostDataメソッドで行うようです。このメソッドで判定した後、実際にイベントが励起されるのは、IPostBackDataHandler.RaisePostBackEventメソッドです。「コントロール実行の有効期間」を見るとわかるとおり、Pageオブジェクトがこの2つのメソッドを呼び出す間に、Loadイベントが発生します。もし、Loadイベントハンドラでデータを変更してしまうと、LoadPostDataメソッドで判定した内容が覆ってしまいます。 私は「Loadイベントハンドラ内に書かれている『ページを初期化するユーザー コードをここに挿入します。』というコメントはバグだ」と考えていますが、Loadイベントまでを“初期化処理”と考えると、このコメントも正しいと言えます。つまり、Windowsアプリケーションでたとえると、Loadイベントが完了した状態が、Windowsフォームの表示が完了した状態である、と。しかし、それぞれのメソッドで“初期化される値”の意味を考えて、「どこで初期化するべきか」をよく考えなければならないでしょう。 そうすると、まずコントロールの追加は、やはりInitイベントで行うべきです。次にそこで追加したコントロールに対する値の変更は、Windowsアプリケーションと照らし合わせても“初期化処理”で行うべきではありません。Loadイベント終了後、IPostBackDataHandler.RaisePostBackEventメソッド以降に行うべきでしょう。 _________________ |
1