- PR -

DataGridのページングでのデータの持ち方

投稿者投稿内容
ryu
常連さん
会議室デビュー日: 2005/07/05
投稿数: 30
投稿日時: 2005-09-20 13:55
先日は色々な質問に答えて頂きありがとうございます。
今回、また問題があり質問させてください。

ASP.net(VB.NET)でDBからDataGridにデータを表示しています。
表示されたDataGridにはチェックボックスを表示してあります。
このDataGridでページング(モードはページ番号です。)をすると当然、前のページのチェックは消えてしまいますよね?
ページが戻った時に表示させたいのですが、色々と調べた結果、セッションを使えば良いって事が書いてあったんです。
セッションを使う場合、どのようにデータを持てば良いのかアドバイスを頂きたいのですが。。。
ページングでページ番号を指定しているとどのページに戻るかわからないのでどうすればいいのかなって思いまして、

よろしくお願い致します。
ぼのぼの
ぬし
会議室デビュー日: 2004/09/16
投稿数: 544
投稿日時: 2005-09-20 15:41
こんにちは。

DBからDataGridってことは、DataSourceにDataSetかDataTableを指定してDataBindしているってことで良いでしょうか?
で、ページングしてるってことは、既にこのDataSetかDataTableはSessionに保持するようにしている?

↑の前提で話を進めると、DataTableにチェックボックス用の列を追加して、そこにチェックボックスのCheckedプロパティの値を保持するようにすればいいんじゃないでしょうか。
DataTable1.Columns.Add("CheckBox", GetType(Boolean))
みたいな感じで。
ryu
常連さん
会議室デビュー日: 2005/07/05
投稿数: 30
投稿日時: 2005-09-21 16:48
返事がかなり遅れてしまって大変申し訳ありませんでした。

すいません。説明が全然足りていませんでした。補足させてください。
DBからDataGridは、プロパティビルダを使って列を指定しています。

ページングもプロパティビルダを使って設定し、PageIndexChangedで再度、DBを
呼んで表示させています。ということでSessionは使っていません。

チェックボックスは、設置済みでプロパティビルダでテンプレート列を追加して
そこにチェックボックスを表示するようにしています。

ページングのページ指定だとどのページに飛ぶのかがわからないので
どのようにSessionに値を持たせてどのようにチェックされているチェックボックスを
再度チェックしてあげれば良いのか全然わかりません。

最終的には、選ばれてた全てのデータでDBからデータを抽出して再度、DataGridに
表示させたいのです。
SE卵
大ベテラン
会議室デビュー日: 2004/10/22
投稿数: 135
投稿日時: 2005-09-21 17:09
>ページングのページ指定だとどのページに飛ぶのかがわからないので
>どのようにSessionに値を持たせてどのようにチェックされているチェックボックスを
>再度チェックしてあげれば良いのか全然わかりません。

んーどのページに飛ぶのかがわからないので、分からない。。。ってのが分からないですね。
どこに飛ぶかなんてユーザが押したページに飛ぶ。


まず、どのようにして、チェックボックスのチェックの有無を知るか?という事

datagridのfindControlを使用すれば、コントロールは取得でき、チェック状態も分かる。
また、チェックの有無の設定も可能。

あと、チェックの状態の保持について。

ページングの際にDBから取得したデータを再度バインドしていると思うのですが、いかが
ですか?バインドすればチェックは消える。

なので、
チェックを保持する配列かなんか作って、それにレコード数分のチェック状態を保持する。
んで、それをセッションに保持する。んで、DatGridのItemDataBound時にさっきいった
findControlでチャック状態の復元を行う。
SE卵
大ベテラン
会議室デビュー日: 2004/10/22
投稿数: 135
投稿日時: 2005-09-21 17:20
簡単な例

1 FindControl
コード:
Dim chkbox As CheckBox

chkbox = CType(dgrdCalcScopeData.Items(行番号).FindControl("チェックボックスのID"), CheckBox)

chkbox.checked = チェックの有無(True/False)



2 ぼのぼのさんと同じ方法
一度始めにDataBindした際に、DataGridのDataSetかDataTableをSessionに保持する。
その後のバインドはSessionに保持しているものをバインドする。そうすれば、たぶん
チェック状態は保持されたままじゃないかな?試してないんで、間違ってたらごめんなさい。


※ 注意
ryuさんはたぶん毎回DBから取得したデータをバインドしてると思うので、それを変えたく
ないのであれば、やはりチェック状態をどっかで保持して、バインドの際に復元してあげる
しかないと思う。
ぼのぼの
ぬし
会議室デビュー日: 2004/09/16
投稿数: 544
投稿日時: 2005-09-21 17:31
引用:

ryuさんの書き込み (2005-09-21 16:48) より:
ページングもプロパティビルダを使って設定し、PageIndexChangedで再度、DBを
呼んで表示させています。ということでSessionは使っていません。


実装方法としては概ねSE卵さんの仰る通りなのですが、ここがちょいと気になりました。逐次DBから取得するということは、ページ移動をした時点でDBにレコードが追加なり削除なりされていたとしたら、インデックスがずれちゃいませんか?DBが絶対に更新されない参照用のテーブルならいいですが、そうでない場合はチェックボックスを単なる配列ではなく、主キーと結びつけたHashtable等で保持しなければいけないでしょう。

これを避けるとなると私が最初に言った方法になりますが、DataTableが巨大ならWebサーバのメモリをたくさん使うことになりますし、表示内容のリアルタイム性が失われるので、どっちの方法が良いかは一概には言えません。
ryu
常連さん
会議室デビュー日: 2005/07/05
投稿数: 30
投稿日時: 2005-09-21 19:43
SE卵さん、ぼのぼのさん本当にありがとうございます。

>SE卵さん
>んーどのページに飛ぶのかがわからないので、分からない。。。ってのが分からないですね。
>どこに飛ぶかなんてユーザが押したページに飛ぶ。

すみません。確かにそうですね。どこを押すかがわからないって意味です。

一応、チェックしたデータの取得はこんな感じでできました。
これを今度チェックの復元の方法がよくわかりません。

Private Sub DataGrid_PageIndexChanged(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridPageChangedEventArgs) Handles DataGrid.PageIndexChanged
Dim Cb As CheckBox
Dim Row As DataGridItem
Dim Cname, Str1, Str2 As String
Dim arryList = New ArrayList

For Each Row In DGD_IRO.Items
Cb = CType(Row.FindControl("CheckBox1"), CheckBox)
Cname = Cb.UniqueID
If Request.Form(Cname) <> "" Then
arryList.Add(Row.Cells(1).Text)
End If
Next
end Sub

>ぼのぼのさん
DataTableを使った方法もある事を初めて知りました。
この方法でも使えるようにしておかないといけないなって思います。
今回は、参照用のテーブルなので大丈夫だと思います。
SE卵
大ベテラン
会議室デビュー日: 2004/10/22
投稿数: 135
投稿日時: 2005-09-22 09:05
コード:
Dim Cb   As CheckBox 
Dim Row  As DataGridItem 
Dim Cname, Str1, Str2 As String 

Dim arryList = New ArrayList 

For Each Row In DGD_IRO.Items 
    Cb = CType(Row.FindControl("CheckBox1"), CheckBox) 
    Cname = Cb.UniqueID 
    
    If Request.Form(Cname) <> "" Then 
        arryList.Add(Row.Cells(1).Text) 
    End If 
Next 



ん?上記コードで取得データを取っているみたいだけど。。。。
セルのテキストで判断するのはどうかな。。。もしセルの位置とか
変わったら変更が大変じゃないですか?こんなのどうでしょう?

コード:
Dim Cb   As CheckBox 
Dim Row  As DataGridItem
Dim Llbl As Label

Dim arryList = New ArrayList 

For Each Row In DGD_IRO.Items 
    Cb = CType(Row.FindControl("CheckBox1"), CheckBox) 
    
    If Cb.Checked Then
        '' チェックされている場合
        '' ここでは例としてラベルコントロールを取得
        Llbl = CType(Row.FindControl("取得したいデータのID"), Label)

        arryList.Add(Trim(Llbl.Text))
    End If
Next 



次に、復元方法については、って全部教えてる気がする。。。
まあいいかあ。この辺の情報は過去ログやMSDNにも載ってるはずなんだけど。。。

復元には、ItemDataBoundイベントを使用する方法があります。
その他にもあると思うので、多少調べてみてはいかがでしょうか?
コード:
Private Sub datagrid_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles datagrid.ItemDataBound
    Dim Cb As CheckBox

    If ((e.Item.ItemType = ListItemType.AlternatingItem) Or (e.Item.ItemType = ListItemType.Item)) Then
        Cb = CType(e.Item.FindControl("CheckBox1"), CheckBox)

        '' ここで、さっき保持していたarrayListの中身を
        '' 入れてあげる。※その前に条件式がいると思うけど
        '' そこはryuさんが考えれば分かる事。
        Cb.Checked = True もしくは False
    End If
End Sub



試してないんで、間違っているとこあったら、ごめんなさい。

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