- PR -

ViewStateの動的オブジェクト対応ついて

1
投稿者投稿内容
R_FOREST
会議室デビュー日: 2003/06/19
投稿数: 4
投稿日時: 2003-06-19 14:44
ViewStateの使用方法について質問です。
Page_Load時にTableオブジェクトにcell,rowを動的に挿入した場合はTable.Rows.Countで件数を確認すると、入力した件数分取得できるのですが、
Page_Load終了後に別イベント(ボタンクリックなど)で件数を確認しても0件となってしまいます。
試しにcell,rowを最初から画面に用意した場合は件数を正しく取得できます。
ViewStateはそもそも最初から用意されたオブジェクトにだけ対して有効なのでしょうか?
さり
常連さん
会議室デビュー日: 2003/05/13
投稿数: 38
投稿日時: 2003-06-19 17:42
いつも質問してばかりなのでお答えします。答えはYESです。
ただ、ViewStateに任意に入れたり取り出したりすることは可能です。

Page_Load処理の終わりで
this.ViewState.Add("table",dt);
dtは作成したDataTableオブジェクトの名称。

button_clickイベントで
DataTable dt = (DataTable)this.ViewState["table"];
で、ViewStateから取り出せます。
R_FOREST
会議室デビュー日: 2003/06/19
投稿数: 4
投稿日時: 2003-06-19 20:13
なるほど、オブジェクトの追加が動的なら、ViewStateの指定も動的に行うと言うことですね。
色々と活用できそうです。
どうもありがとうございました。
AOPP
ベテラン
会議室デビュー日: 2002/11/18
投稿数: 66
投稿日時: 2003-09-30 22:54
aoppです。

Tableクラスを使用して動的に配置した画面を作成しております。
早速 ViewStateに、Tableオブジェクトを保存しポストバック時に取得しようとしたのですが
Tableクラス(System.Web.UI.WebControls.Table)は、シリアル化されてないので、
ViewStateの保存時、エラーが出ます。(シリアル化するようにと)
TableクラスはSerializable属性が設定されている型なのでしょうか!!!

Tableクラスにシリアル化にする方法をご存知のかた教えてください。

もうひとつ気になることがあるのですが!!
動的に配置したドロップダウンリストなどは、Page_Loadで毎回インスタンス化して
プロパティに情報を設定しております。(ViewStateに保存されないため・なぜだろう)
以下のテストをしたところViewStateに保存されホストバック時に、ドロップダウンリスト
などのクラスをインスタンス化しプロパティのIDのみ設定したところ他のプロパティ情報が
ホストバック時に画面に反映されました。(色・サイズ・データ)

トレースでViewStateの状態を監視しました
1.初期起動
 ViewStateのドロップダウンリストなど0バイト
2.画面からボタンクリック処理なし(ポストバック)
 ViewStateのドロップダウンリストなど100バイト(何か情報が保存された)
3.画面からボタンクリック処理なし(ポストバック)
 Page_Loadで2回以上のポストバックの場合、ドロップダウンリスト
 などのクラスをインスタンス化しプロパティのIDのみ設定の処理にした。
 ViewStateのドロップダウンリストなど100バイト(何か情報が保存された値変わらず)
 画面も静的の場合と同等に動作した

どういうことですかね!!イベント発生後のポストバック時に、動的に配置したオブジェクト
情報がViewStateに保存されている。静的に配置したオブジェクトは、常にユーザー側ですべて
考慮しないと思っていたのに、もしかして静的に配置したオブジェクトをViewStateに保存する
方法があるのではないかとおもっます。なにかご意見・情報があればお願いします。
いろいろためしたがViewStateに保存できない。(EnableViewState = Trueなど)

 


Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2003-10-01 09:31
引用:

AOPPさんの書き込み (2003-09-30 22:54) より:

Tableクラス(System.Web.UI.WebControls.Table)は、シリアル化されてないので、
ViewStateの保存時、エラーが出ます。(シリアル化するようにと)
TableクラスはSerializable属性が設定されている型なのでしょうか!!!

Tableクラスにシリアル化にする方法をご存知のかた教えてください。


 同じことでハマりました。DataTableはSerializable属性が付いているのに、シリアライズできません。ところが、DataSetの中にはいると、DataSetと共にシリアライズできます。簡単にすますは、DataSetに放り込めばいいです。

[ メッセージ編集済み 編集者: Jitta 編集日時 2003-10-01 09:31 ]
AOPP
ベテラン
会議室デビュー日: 2002/11/18
投稿数: 66
投稿日時: 2003-10-01 09:39
aoppです

Tableクラス(System.Web.UI.WebControls.Table)をDataSetに放りこめるとは知らなかった。DataTable(System.Data)は、確かにDataSetに放り込んでやらないことは、知っていたが
やって見ます。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2003-10-01 12:18
引用:

AOPPさんの書き込み (2003-10-01 09:39) より:

Tableクラス(System.Web.UI.WebControls.Table)をDataSetに放りこめるとは知らなかった。DataTable(System.Data)は、確かにDataSetに放り込んでやらないことは、知っていたが
やって見ます。


わぁ!!すみません、勘違いです。ちゃんと名前空間も書いてあるのに、見間違えていました。ごめんなさい。


 シリアル化するには・・・Serialize属性が付いていないので、そのままではシリアライズできません。そこで、Serializable属性をつけたWebControlに継承させます。ところが、継承元をシリアライズするときに、やはりシリアライズできないので、ISerializableインタフェースを実装し、自分でシリアライズします。

<system.Serializable()> Public Class SerializableTable
Inherits System.Web.UI.WebControls.Table
Implements System.Runtime.Serialization.ISerializable

ここで、2つのメソッド追加します。1つはシリアライズメソッド、もう1つはデシリアライズコンストラクタです。

Public Sub GetObjectData(ByVal info As _
System.Runtime.Serialization.SerializationInfo, _
ByVal context As System.Runtime.Serialization.StreamingContext) _
Implements System.Runtime.Serialization.ISerializable.GetObjectData

Protected Sub New(ByVal info As _
System.Runtime.Serialization.SerializationInfo, _
ByVal context As System.Runtime.Serialization.StreamingContext)

やることは単純。GetObjectDataではinfo.AddValueで、すべてのプロパティを書き出し、反対にProtected Sub NewではInfo.Get??で取り出します。問題はWebAttributeCollectionですが、
Dim AttrNames As String
Dim keys As IEnumerator = .Attributes.Keys.GetEnumerator
Do While keys.MoveNext
Dim key As String = keys.Current
AttrNames &= "::" & key
info.AddValue(.Attributes(key), GetType(String))
Loop
info.AddValue("AttributeNames", AttrNames, GetType(String))

こんな感じで個別にシリアライズし、取り出すときは先にAttributeNamesを取り出し、そこから属性名に切り分けて、名前を指定していけばよいでしょう。



一応、簡単に確認しました。WebControlプロジェクトを作ってDLLを参照させるとツールボックスにもおけます。WebControlLibraryのプロジェクトを作った場合は、Renderメソッドのオーバライドを必ず外してください。

 勘違いから混乱させまして、お詫びします。
AOPP
ベテラン
会議室デビュー日: 2002/11/18
投稿数: 66
投稿日時: 2003-10-01 12:50
aoppです

よかった勘違いか私のスキルが無いのかと思った(ビルドエラーがでますね)

引用:
--------------------------------------------------------------------------------
Serializable属性をつけたWebControlに継承させます。ところが、継承元をシリアライズするときに、やはりシリアライズできないので、ISerializableインタフェースを実装し、自分でシリアライズします。
--------------------------------------------------------------------------------

なるほどね
Jittaさん説明・コードありがとうございます。
以後、別でも使えそうなものですね!!!
1

スキルアップ/キャリアアップ(JOB@IT)